tag:blogger.com,1999:blog-1064497754389466612024-03-18T02:48:20.103-07:00Overcoming FearAn open exploration of what I do not know.Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.comBlogger63125tag:blogger.com,1999:blog-106449775438946661.post-32982510032620914812014-04-27T01:26:00.000-07:002014-04-30T22:49:29.147-07:00Contributing to the Papyrus Editor Palette<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Augmenting the Papyrus Palette</title>
</head>
<body>
<h4>
<a id="Goal">Goal</a>
</h4>
<p>
This entry is the first in a series of articles that details the customizations to the Eclipse <a
href="https://www.eclipse.org/papyrus/">Papyrus</a> platform for the <a
href="https://github.com/timezra/UML-Testing-Tool">UML Testing Tool</a>. These customizations, though specific to the
needs of the <a href="https://github.com/timezra/UML-Testing-Tool">UML Testing Tool</a> community, can be generalized
and used for other products with similar requirements.
</p>
<p>
The <a href="https://github.com/timezra/UML-Testing-Tool">UML Testing Tool</a> is a graphical workbench for the
design, visualization, specification, analysis, construction, and documentation of the artifacts involved in testing.
The language for modeling these artifacts is based on a <a href="http://utp.omg.org/">UML Testing Profile</a>. This
profile defines a set of UML stereotypes that extend a subset of UML elements. There are <a
href="https://github.com/info-sharing-environment/NIEM-Modeling-Tool">Similar tools</a> based on <a
href="http://www.omg.org/spec">other UML profile specifications</a>, such as the <a
href="http://www.omg.org/spec/NIEM-UML/">NIEM UML Profile</a>.
</p>
<p>
<a href="https://www.eclipse.org/papyrus/">Papyrus</a> is an environment within <a href="http://www.eclipse.org/">Eclipse</a>
that enables users to configure graphical editors for UML-based DSLs.
</p>
<p>
The goal of this first entry is to describe how to register a UML profile with <a
href="https://www.eclipse.org/papyrus/">Papyrus</a> and to augment the <a href="https://www.eclipse.org/papyrus/">Papyrus</a>
editor palette with stereotyped elements defined in this profile.
</p>
<h4>
<a id="TLDR">tl;dr</a>
</h4>
<p>
The source code for the set of Eclipse plug-ins that contains the UML Testing Profile, its registrations with the
Eclipse UML and Papyrus extensions and the test cases described in this post is located <a
href="https://github.com/timezra/UML-Testing-Tool">here</a>. Feel free to use, explore, contribute to or fork this
code for your own needs. A snapshot of the code specific to these examples at the time of writing is <a
href="https://github.com/timezra/UML-Testing-Tool/releases/tag/v1.0.0.PaletteDefinition">here</a>.
</p>
<h4>
<a id="Dynamic_Package_Registration">Registering the UML Profile</a>
</h4>
<p>
Let's assume that we already have all the boilerplate configuration for an Eclipse plug-in, test fragment, feature and
p2-repository in place. For this plug-in, we can use the <a href="https://github.com/timezra/tycho_new_plugin_project">tycho_new_plugin_project
archetype</a>, initially described <a href="http://timezra.blogspot.com/2011/10/tycho-archetype.html">here</a>.
</p>
<p>We will start with an acceptance test to verify that we have correctly registered the UML Testing Profile as a
UML dynamic package.</p>
<em>PackageRegistrationTest.java</em>
<div>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>PackageRegistrationTest.java</title>
<style type="text/css">
div.cm_source {
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin;
font-family: monospace;
font-size: 10pt;
white-space: nowrap;
}
span.cm_b_n_n_7F0055 {
font-weight: bold;
color: #7F0055;
}
span.cm_n_n_n_0 {
color: #000000;
}
span.cm_n_n_n_2A00FF {
color: #2A00FF;
}
</style>
</head>
<body>
<div class="cm_source">
<span class="cm_b_n_n_7F0055">package</span><span class="cm_n_n_n_0"> timezra.uml.testing.resources;<br />
<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">static</span><span
class="cm_n_n_n_0"> org.eclipse.uml2.uml.UMLPlugin.getEPackageNsURIToProfileLocationMap;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">static</span><span
class="cm_n_n_n_0"> org.eclipse.uml2.uml.resources.util.UMLResourcesUtil.init;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">static</span><span
class="cm_n_n_n_0"> org.hamcrest.CoreMatchers.instanceOf;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">static</span><span
class="cm_n_n_n_0"> org.junit.Assert.assertThat;<br /> <br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.emf.ecore.EObject;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.uml2.uml.Profile;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.junit.Test;<br /> <br />
</span><span class="cm_b_n_n_7F0055">public</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">class</span><span
class="cm_n_n_n_0"> PackageRegistrationTest {<br /> @Test<br />
</span><span class="cm_b_n_n_7F0055">public</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">void</span><span
class="cm_n_n_n_0"> should_register_the_uml_testing_package() {<br />
</span><span class="cm_b_n_n_7F0055">final</span><span class="cm_n_n_n_0"> EObject utp = init(</span><span
class="cm_b_n_n_7F0055">new</span><span class="cm_n_n_n_0"> ResourceSetImpl()).getEObject(<br />
getEPackageNsURIToProfileLocationMap().get(
</span><span class="cm_n_n_n_2A00FF">"http://www.omg.org/spec/UTP/20120801/utp_1.2"</span><span class="cm_n_n_n_0">), </span><span
class="cm_b_n_n_7F0055">true</span><span class="cm_n_n_n_0">);<br /> <br />
assertThat(utp, instanceOf(Profile.
</span><span class="cm_b_n_n_7F0055">class</span><span class="cm_n_n_n_0">));<br /> }<br />
}<br />
</span>
</div>
</body>
</html>
</div>
<br />
<p>
In order to satisfy this test, we must include the <a href="http://www.omg.org/spec/UTP/20120801/utp_1.2.xmi">utp_1.2.xmi</a>
and <a href="http://www.omg.org/spec/UTP/20120801/utptypes_1.2.xmi">utptypes_1.2.xmi</a> with our plug-in. We will
modify the <a href="http://www.omg.org/spec/UTP/20120801/utp_1.2.xmi">utp_1.2.xmi</a> by adding the xmlns declaration
<span style="color: #7F007F">xmlns:cmof</span>=<span style="font-style: italic; color: #2A00FF;">"http://www.omg.org/spec/MOF/20110701/cmof.xmi"</span>
to the root header. We also need to define the profile through the Eclipse UML Editor.
</p>
<p>With the UTP and its supporting type descriptions packaged into a plug-in, we can now register an extension for
the UML dynamic package for the profile we just defined through the Eclipse UML Editor.</p>
<em>plugin.xml</em>
<div>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>plugin.xml</title>
<style type="text/css">
div.cm_source {
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin;
font-family: monospace;
font-size: 10pt;
white-space: nowrap;
}
span.cm_n_n_n_8080 {
color: #008080;
}
span.cm_n_n_n_3F7F7F {
color: #3F7F7F;
}
span.cm_n_n_n_7F007F {
color: #7F007F;
}
span.cm_n_i_n_2A00FF {
font-style: italic;
color: #2A00FF;
}
</style>
</head>
<body>
<div class="cm_source">
<span class="cm_n_n_n_8080"><?</span><span class="cm_n_n_n_3F7F7F">xml</span> <span class="cm_n_n_n_7F007F">version</span>=<span
class="cm_n_i_n_2A00FF">"1.0"</span> <span class="cm_n_n_n_7F007F">encoding</span>=<span
class="cm_n_i_n_2A00FF">"UTF-8"</span><span class="cm_n_n_n_8080">?></span><br /> <span
class="cm_n_n_n_8080"><?</span><span class="cm_n_n_n_3F7F7F">eclipse</span> version="3.4"<span
class="cm_n_n_n_8080">?></span><br /> <span class="cm_n_n_n_8080"><</span><span class="cm_n_n_n_3F7F7F">plugin</span><span
class="cm_n_n_n_8080">></span><br /> <span class="cm_n_n_n_8080"><</span><span
class="cm_n_n_n_3F7F7F">extension</span> <span class="cm_n_n_n_7F007F">point</span>=<span
class="cm_n_i_n_2A00FF">"org.eclipse.emf.ecore.uri_mapping"</span><span class="cm_n_n_n_8080">></span><br />
<span class="cm_n_n_n_8080"><</span><span class="cm_n_n_n_3F7F7F">mapping</span> <span
class="cm_n_n_n_7F007F">source</span>=<span class="cm_n_i_n_2A00FF">"pathmap://UTP/"</span><br />
<span class="cm_n_n_n_7F007F">target</span>=<span
class="cm_n_i_n_2A00FF">"platform:/plugin/timezra.uml.testing.resources/src/main/resources/uml/"</span><span
class="cm_n_n_n_8080">></span><br /> <span class="cm_n_n_n_8080"></</span><span
class="cm_n_n_n_3F7F7F">mapping</span><span class="cm_n_n_n_8080">></span><br /> <span
class="cm_n_n_n_8080"></</span><span class="cm_n_n_n_3F7F7F">extension</span><span class="cm_n_n_n_8080">></span><br />
<span class="cm_n_n_n_8080"><</span><span class="cm_n_n_n_3F7F7F">extension</span> <span
class="cm_n_n_n_7F007F">point</span>=<span class="cm_n_i_n_2A00FF">"org.eclipse.emf.ecore.uri_mapping"</span><span
class="cm_n_n_n_8080">></span><br /> <span class="cm_n_n_n_8080"><</span><span
class="cm_n_n_n_3F7F7F">mapping</span> <span class="cm_n_n_n_7F007F">source</span>=<span class="cm_n_i_n_2A00FF">"http://www.omg.org/spec/UTP/20120801/utp_1.2.xmi"</span><br />
<span class="cm_n_n_n_7F007F">target</span>=<span
class="cm_n_i_n_2A00FF">"pathmap://UTP/utp_1.2.xmi"</span><span class="cm_n_n_n_8080">></span><br />
<span class="cm_n_n_n_8080"></</span><span class="cm_n_n_n_3F7F7F">mapping</span><span
class="cm_n_n_n_8080">></span><br /> <span class="cm_n_n_n_8080"><</span><span
class="cm_n_n_n_3F7F7F">mapping</span> <span class="cm_n_n_n_7F007F">source</span>=<span class="cm_n_i_n_2A00FF">"http://www.omg.org/spec/UTP/20120801/utptypes_1.2.xmi"</span><br />
<span class="cm_n_n_n_7F007F">target</span>=<span
class="cm_n_i_n_2A00FF">"pathmap://UTP/utptypes_1.2.xmi"</span><span class="cm_n_n_n_8080">></span><br />
<span class="cm_n_n_n_8080"></</span><span class="cm_n_n_n_3F7F7F">mapping</span><span
class="cm_n_n_n_8080">></span><br /> <span class="cm_n_n_n_8080"></</span><span
class="cm_n_n_n_3F7F7F">extension</span><span class="cm_n_n_n_8080">></span><br /> <span
class="cm_n_n_n_8080"><</span><span class="cm_n_n_n_3F7F7F">extension</span> <span class="cm_n_n_n_7F007F">point</span>=<span
class="cm_n_i_n_2A00FF">"org.eclipse.uml2.uml.dynamic_package"</span><span class="cm_n_n_n_8080">></span><br />
<span class="cm_n_n_n_8080"><</span><span class="cm_n_n_n_3F7F7F">profile</span> <span
class="cm_n_n_n_7F007F">location</span>=<span class="cm_n_i_n_2A00FF">"pathmap://UTP/utp_1.2.xmi#_iCl4wOVMEeG84fBOY39c0g"</span><br />
<span class="cm_n_n_n_7F007F">uri</span>=<span
class="cm_n_i_n_2A00FF">"http://www.omg.org/spec/UTP/20120801/utp_1.2"</span><span class="cm_n_n_n_8080">></span><br />
<span class="cm_n_n_n_8080"></</span><span class="cm_n_n_n_3F7F7F">profile</span><span
class="cm_n_n_n_8080">></span><br /> <span class="cm_n_n_n_8080"></</span><span
class="cm_n_n_n_3F7F7F">extension</span><span class="cm_n_n_n_8080">></span><br /> <span class="cm_n_n_n_8080"></</span><span
class="cm_n_n_n_3F7F7F">plugin</span><span class="cm_n_n_n_8080">></span><br />
</div>
</body>
</html>
</div>
<br />
<p>
Now, if we install our feature into Eclipse and create a new UML model, the UTP will be available for profile
application through the UML Editor. <img alt="UTP Registered With UML"
src="http://farm8.staticflickr.com/7083/14006419266_0d88fddce0_b.jpg" />
</p>
<h4>
<a id="Profile_Registration">Profile Registration With Papyrus</a>
</h4>
<p>In order to register this profile with Papyrus, we can use similar steps: create a test to verify when the
behavior we are trying to expose works and expose the profile location through an extension.</p>
<em>ProfileRegistrationTest.java</em>
<div>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ProfileRegistrationTest.java</title>
<style type="text/css">
div.cm_source {
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin;
font-family: monospace;
font-size: 10pt;
white-space: nowrap;
}
span.cm_b_n_n_7F0055 {
font-weight: bold;
color: #7F0055;
}
span.cm_n_n_n_0 {
color: #000000;
}
span.cm_n_n_n_2A00FF {
color: #2A00FF;
}
</style>
</head>
<body>
<div class="cm_source">
<span class="cm_b_n_n_7F0055">package</span><span class="cm_n_n_n_0"> timezra.uml.testing.papyrus.palettes;<br />
<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">static</span><span
class="cm_n_n_n_0"> org.eclipse.papyrus.uml.extensionpoints.profile.RegisteredProfile.getRegisteredProfile;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">static</span><span
class="cm_n_n_n_0"> org.hamcrest.CoreMatchers.notNullValue;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">static</span><span
class="cm_n_n_n_0"> org.junit.Assert.assertThat;<br /> <br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.junit.Test;<br /> <br />
</span><span class="cm_b_n_n_7F0055">public</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">class</span><span
class="cm_n_n_n_0"> ProfileRegistrationTest {<br /> @Test<br />
</span><span class="cm_b_n_n_7F0055">public</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">void</span><span
class="cm_n_n_n_0"> should_register_the_uml_testing_profile() {<br />
assertThat(getRegisteredProfile(
</span><span class="cm_n_n_n_2A00FF">"UTP"</span><span class="cm_n_n_n_0">), notNullValue());<br />
}<br /> }<br />
</span>
</div>
</body>
</html>
</div>
<br />
<em>plugin.xml</em>
<div>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>plugin.xml</title>
<style type="text/css">
div.cm_source {
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin;
font-family: monospace;
font-size: 10pt;
white-space: nowrap;
}
span.cm_n_n_n_8080 {
color: #008080;
}
span.cm_n_n_n_3F7F7F {
color: #3F7F7F;
}
span.cm_n_n_n_7F007F {
color: #7F007F;
}
span.cm_n_i_n_2A00FF {
font-style: italic;
color: #2A00FF;
}
</style>
</head>
<body>
<div class="cm_source">
....<br /> <span class="cm_n_n_n_8080"><</span><span class="cm_n_n_n_3F7F7F">extension</span><br />
<span class="cm_n_n_n_7F007F">point</span>=<span
class="cm_n_i_n_2A00FF">"org.eclipse.papyrus.uml.extensionpoints.UMLProfile"</span><span
class="cm_n_n_n_8080">></span><br /> <span class="cm_n_n_n_8080"><</span><span
class="cm_n_n_n_3F7F7F">profile</span><br />
<span class="cm_n_n_n_7F007F">description</span>=<span
class="cm_n_i_n_2A00FF">"UML Testing Profile"</span><br />
<span class="cm_n_n_n_7F007F">iconpath</span>=<span
class="cm_n_i_n_2A00FF">"icons/full/obj16/utp.png"</span><br />
<span class="cm_n_n_n_7F007F">name</span>=<span
class="cm_n_i_n_2A00FF">"UTP"</span><br />
<span class="cm_n_n_n_7F007F">path</span>=<span
class="cm_n_i_n_2A00FF">"http://www.omg.org/spec/UTP/20120801/utp_1.2.xmi#_iCl4wOVMEeG84fBOY39c0g"</span><br />
<span class="cm_n_n_n_7F007F">provider</span>=<span
class="cm_n_i_n_2A00FF">"omg.org"</span><span class="cm_n_n_n_8080">></span><br />
<span class="cm_n_n_n_8080"></</span><span class="cm_n_n_n_3F7F7F">profile</span><span
class="cm_n_n_n_8080">></span><br /> <span class="cm_n_n_n_8080"></</span><span
class="cm_n_n_n_3F7F7F">extension</span><span class="cm_n_n_n_8080">></span><br /> <span
class="cm_n_n_n_8080"><</span><span class="cm_n_n_n_3F7F7F">extension</span><br />
<span class="cm_n_n_n_7F007F">point</span>=<span
class="cm_n_i_n_2A00FF">"org.eclipse.papyrus.uml.extensionpoints.UMLLibrary"</span><span
class="cm_n_n_n_8080">></span><br /> <span class="cm_n_n_n_8080"><</span><span
class="cm_n_n_n_3F7F7F">library</span><br />
<span class="cm_n_n_n_7F007F">description</span>=<span
class="cm_n_i_n_2A00FF">"UML Testing Profile Types"</span><br />
<span class="cm_n_n_n_7F007F">iconpath</span>=<span
class="cm_n_i_n_2A00FF">"icons/full/obj16/utptypes.png"</span><br />
<span class="cm_n_n_n_7F007F">name</span>=<span
class="cm_n_i_n_2A00FF">"UTP Types"</span><br />
<span class="cm_n_n_n_7F007F">path</span>=<span
class="cm_n_i_n_2A00FF">"http://www.omg.org/spec/UTP/20120801/utptypes_1.2.xmi"</span><br />
<span class="cm_n_n_n_7F007F">provider</span>=<span
class="cm_n_i_n_2A00FF">"omg.org"</span><span class="cm_n_n_n_8080">></span><br />
<span class="cm_n_n_n_8080"></</span><span class="cm_n_n_n_3F7F7F">library</span><span
class="cm_n_n_n_8080">></span><br /> <span class="cm_n_n_n_8080"></</span><span
class="cm_n_n_n_3F7F7F">extension</span><span class="cm_n_n_n_8080">></span><br /> ....
</div>
</body>
</html>
</div>
<br />
<p>
The UTP is now available in the Papyrus repository, and it can be applied from the Profile tab of the Properties View.
<img alt="UTP Registered With Papyrus" src="http://farm6.staticflickr.com/5271/14049682723_7ddfd9c00f_b.jpg" width=800 />
</p>
<h4>
<a id="Palette_Customization">Palette Customization</a>
</h4>
<p>Once we are able to apply the UTP to a Model, we can specify tests with UML elements extended by this profile.
Suppose we begin by creating a TestContext from the Papyrus palette.</p>
<em>ClassDiagramPaletteTest.java</em>
<div>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ClassDiagramPaletteTest.java</title>
<style type="text/css">
div.cm_source_ClassDiagramPaletteTest {
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin;
font-family: monospace;
font-size: 10pt;
white-space: nowrap;
height: 93em;
}
span.cm_b_n_n_7F0055 {
font-weight: bold;
color: #7F0055;
}
span.cm_n_n_n_0 {
color: #000000;
}
span.cm_n_n_n_2A00FF {
color: #2A00FF;
}
</style>
</head>
<body>
<div class="cm_source_ClassDiagramPaletteTest">
<span class="cm_b_n_n_7F0055">package</span><span class="cm_n_n_n_0"> timezra.uml.testing.papyrus.palettes;<br />
<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">static</span><span
class="cm_n_n_n_0"> org.eclipse.papyrus.uml.diagram.common.util.URIUtil.getFile;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">static</span><span
class="cm_n_n_n_0"> org.eclipse.papyrus.uml.tools.model.UmlUtils.getUmlResource;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">static</span><span
class="cm_n_n_n_0"> org.hamcrest.CoreMatchers.instanceOf;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">static</span><span
class="cm_n_n_n_0"> org.hamcrest.CoreMatchers.notNullValue;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">static</span><span
class="cm_n_n_n_0"> org.junit.Assert.assertThat;<br /> <br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.gef.EditDomain;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.gef.EditPartViewer;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.gef.Tool;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.gef.palette.PaletteContainer;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.gef.palette.PaletteEntry;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.gef.palette.ToolEntry;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.gef.ui.palette.PaletteViewer;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.gmf.runtime.diagram.ui.editparts.IGraphicalEditPart;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.gmf.runtime.diagram.ui.parts.IDiagramWorkbenchPart;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.papyrus.editor.PapyrusMultiDiagramEditor;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.papyrus.infra.core.editor.IMultiDiagramEditor;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.papyrus.uml.diagram.clazz.CreateClassDiagramCommand;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.swt.events.MouseEvent;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.swt.widgets.Event;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.uml2.uml.Class;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.uml2.uml.Element;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.eclipse.uml2.uml.Package;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.junit.Rule;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.junit.Test;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.junit.rules.RuleChain;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> org.junit.rules.TestRule;<br /> <br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> timezra.uml.testing.papyrus.palettes.rules.AppliesTheUTP;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> timezra.uml.testing.papyrus.palettes.rules.CreatesAPapyrusModel;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> timezra.uml.testing.papyrus.palettes.rules.CreatesAProject;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> timezra.uml.testing.papyrus.palettes.rules.CreatesAServicesRegistry;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> timezra.uml.testing.papyrus.palettes.rules.OpensEditor;<br />
</span><span class="cm_b_n_n_7F0055">import</span><span class="cm_n_n_n_0"> timezra.uml.testing.papyrus.palettes.rules.SavesAModel;<br />
<br />
</span><span class="cm_b_n_n_7F0055">public</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">class</span><span
class="cm_n_n_n_0"> ClassDiagramPaletteTest {<br /> <br />
</span><span class="cm_b_n_n_7F0055">private</span><span class="cm_n_n_n_0"> CreatesAServicesRegistry theServicesRegistry;<br />
</span><span class="cm_b_n_n_7F0055">private</span><span class="cm_n_n_n_0"> CreatesAProject theProject;<br />
</span><span class="cm_b_n_n_7F0055">private</span><span class="cm_n_n_n_0"> CreatesAPapyrusModel thePapyrusModel;<br />
</span><span class="cm_b_n_n_7F0055">private</span><span class="cm_n_n_n_0"> OpensEditor<IMultiDiagramEditor> theEditor;<br />
<br /> @Rule<br />
</span><span class="cm_b_n_n_7F0055">public</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">final</span><span
class="cm_n_n_n_0"> TestRule ruleChain = RuleChain<br />
.outerRule(theServicesRegistry =
</span><span class="cm_b_n_n_7F0055">new</span><span class="cm_n_n_n_0"> CreatesAServicesRegistry())<br />
.around(theProject =
</span><span class="cm_b_n_n_7F0055">new</span><span class="cm_n_n_n_0"> CreatesAProject(getClass().getSimpleName()))<br />
.around(thePapyrusModel =
</span><span class="cm_b_n_n_7F0055">new</span><span class="cm_n_n_n_0"> CreatesAPapyrusModel(theServicesRegistry, theProject, </span><span
class="cm_n_n_n_2A00FF">"model.di"</span><span class="cm_n_n_n_0">,<br />
</span><span class="cm_b_n_n_7F0055">new</span><span class="cm_n_n_n_0"> CreateClassDiagramCommand()))<br />
.around(
</span><span class="cm_b_n_n_7F0055">new</span><span class="cm_n_n_n_0"> AppliesTheUTP(thePapyrusModel))<br />
.around(
</span><span class="cm_b_n_n_7F0055">new</span><span class="cm_n_n_n_0"> SavesAModel(thePapyrusModel))<br />
.around(theEditor =
</span><span class="cm_b_n_n_7F0055">new</span><span class="cm_n_n_n_0"> OpensEditor<IMultiDiagramEditor>(<br />
() -> getFile(getUmlResource(thePapyrusModel.get()).getURI()), PapyrusMultiDiagramEditor.EDITOR_ID));<br />
<br /> @Test<br />
</span><span class="cm_b_n_n_7F0055">public</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">void</span><span
class="cm_n_n_n_0"> can_create_a_test_context() {<br />
</span><span class="cm_b_n_n_7F0055">final</span><span class="cm_n_n_n_0"> IGraphicalEditPart theActivePart = ((IDiagramWorkbenchPart) theEditor.get().getActiveEditor())<br />
.getDiagramEditPart();<br />
</span><span class="cm_b_n_n_7F0055">final</span><span class="cm_n_n_n_0"> EditPartViewer theEditPartViewer = theActivePart.getViewer();<br />
doubleClick(findThePaletteTool(theEditPartViewer,
</span><span class="cm_n_n_n_2A00FF">"UTP/Test Context (Class)"</span><span class="cm_n_n_n_0">), theEditPartViewer);<br />
<br />
</span><span class="cm_b_n_n_7F0055">final</span><span class="cm_n_n_n_0"> Element theTestContext = ((Package) theActivePart.resolveSemanticElement())<br />
.getPackagedElement(
</span><span class="cm_n_n_n_2A00FF">"TestContext1"</span><span class="cm_n_n_n_0">);<br /> <br />
assertThat(theTestContext, instanceOf(Class.
</span><span class="cm_b_n_n_7F0055">class</span><span class="cm_n_n_n_0">));<br />
assertThat(theTestContext.getAppliedStereotype(
</span><span class="cm_n_n_n_2A00FF">"utp::TestContext"</span><span class="cm_n_n_n_0">), notNullValue());<br />
}<br /> <br />
</span><span class="cm_b_n_n_7F0055">private</span><span class="cm_n_n_n_0"> Tool findThePaletteTool(</span><span
class="cm_b_n_n_7F0055">final</span><span class="cm_n_n_n_0"> EditPartViewer theEditPartViewer, </span><span
class="cm_b_n_n_7F0055">final</span><span class="cm_n_n_n_0"> String toolPath) {<br />
</span><span class="cm_b_n_n_7F0055">final</span><span class="cm_n_n_n_0"> EditDomain theDomain = theEditPartViewer.getEditDomain();<br />
</span><span class="cm_b_n_n_7F0055">final</span><span class="cm_n_n_n_0"> PaletteViewer thePaletteViewer = theDomain.getPaletteViewer();<br />
</span><span class="cm_b_n_n_7F0055">final</span><span class="cm_n_n_n_0"> ToolEntry toolEntry = findByLabel(thePaletteViewer.getPaletteRoot(), toolPath);<br />
thePaletteViewer.setActiveTool(toolEntry);<br /> <br />
</span><span class="cm_b_n_n_7F0055">final</span><span class="cm_n_n_n_0"> Tool theTool = toolEntry.createTool();<br />
theTool.setViewer(theEditPartViewer);<br />
theTool.setEditDomain(theDomain);<br /> <br />
</span><span class="cm_b_n_n_7F0055">return</span><span class="cm_n_n_n_0"> theTool;<br />
}<br /> <br /> @SuppressWarnings(
</span><span class="cm_n_n_n_2A00FF">"unchecked"</span><span class="cm_n_n_n_0">)<br />
</span><span class="cm_b_n_n_7F0055">private</span><span class="cm_n_n_n_0"> <T </span><span
class="cm_b_n_n_7F0055">extends</span><span class="cm_n_n_n_0"> PaletteEntry> T findByLabel(</span><span
class="cm_b_n_n_7F0055">final</span><span class="cm_n_n_n_0"> PaletteContainer thePaletteContainer, </span><span
class="cm_b_n_n_7F0055">final</span><span class="cm_n_n_n_0"> String theLabel) {<br />
</span><span class="cm_b_n_n_7F0055">final</span><span class="cm_n_n_n_0"> String[] path = theLabel.split(</span><span
class="cm_n_n_n_2A00FF">"/"</span><span class="cm_n_n_n_0">);<br />
PaletteEntry nextEntry = thePaletteContainer;<br />
NEXT_SEGMENT:
</span><span class="cm_b_n_n_7F0055">for</span><span class="cm_n_n_n_0"> (</span><span class="cm_b_n_n_7F0055">final</span><span
class="cm_n_n_n_0"> String segment : path) {<br />
</span><span class="cm_b_n_n_7F0055">if</span><span class="cm_n_n_n_0"> (nextEntry </span><span
class="cm_b_n_n_7F0055">instanceof</span><span class="cm_n_n_n_0"> PaletteContainer) {<br />
</span><span class="cm_b_n_n_7F0055">for</span><span class="cm_n_n_n_0"> (</span><span class="cm_b_n_n_7F0055">final</span><span
class="cm_n_n_n_0"> Object o : ((PaletteContainer) nextEntry).getChildren()) {<br />
</span><span class="cm_b_n_n_7F0055">final</span><span class="cm_n_n_n_0"> PaletteEntry paletteEntry = (PaletteEntry) o;<br />
</span><span class="cm_b_n_n_7F0055">if</span><span class="cm_n_n_n_0"> (segment.equals(paletteEntry.getLabel())) {<br />
nextEntry = paletteEntry;<br />
</span><span class="cm_b_n_n_7F0055">continue</span><span class="cm_n_n_n_0"> NEXT_SEGMENT;<br />
}<br />
}<br />
</span><span class="cm_b_n_n_7F0055">return</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">null</span><span
class="cm_n_n_n_0">;<br /> }
</span><span class="cm_b_n_n_7F0055">else</span><span class="cm_n_n_n_0"> {<br />
</span><span class="cm_b_n_n_7F0055">return</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">null</span><span
class="cm_n_n_n_0">;<br /> }<br />
}<br />
</span><span class="cm_b_n_n_7F0055">return</span><span class="cm_n_n_n_0"> (T) nextEntry;<br />
}<br /> <br />
</span><span class="cm_b_n_n_7F0055">private</span><span class="cm_n_n_n_0"> </span><span class="cm_b_n_n_7F0055">void</span><span
class="cm_n_n_n_0"> doubleClick(</span><span class="cm_b_n_n_7F0055">final</span><span class="cm_n_n_n_0"> Tool theTool, </span><span
class="cm_b_n_n_7F0055">final</span><span class="cm_n_n_n_0"> EditPartViewer theEditPartViewer) {<br />
</span><span class="cm_b_n_n_7F0055">final</span><span class="cm_n_n_n_0"> Event theEvent = </span><span
class="cm_b_n_n_7F0055">new</span><span class="cm_n_n_n_0"> Event();<br />
theEvent.widget = theEditPartViewer.getControl();<br />
</span><span class="cm_b_n_n_7F0055">final</span><span class="cm_n_n_n_0"> MouseEvent mouseEvent = </span><span
class="cm_b_n_n_7F0055">new</span><span class="cm_n_n_n_0"> MouseEvent(theEvent);<br />
mouseEvent.button = 1;<br />
theTool.mouseDoubleClick(mouseEvent, theEditPartViewer);<br />
}<br /> }<br />
</span>
</div>
</body>
</html>
</div>
<br />
<p>
Now we will describe a palette entry for the Class Diagram Editor that is in a UTP drawer and that will apply the <strong>utp::TestContext</strong>
stereotype to a UML class.
</p>
<em>UTP.clazz.palette.xml</em>
<div>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>UTP.clazz.palette.xml</title>
<style type="text/css">
div.cm_source {
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin;
font-family: monospace;
font-size: 10pt;
white-space: nowrap;
}
span.cm_n_n_n_8080 {
color: #008080;
}
span.cm_n_n_n_3F7F7F {
color: #3F7F7F;
}
span.cm_n_n_n_7F007F {
color: #7F007F;
}
span.cm_n_i_n_2A00FF {
font-style: italic;
color: #2A00FF;
}
</style>
</head>
<body>
<div class="cm_source">
<span class="cm_n_n_n_8080"><?</span><span class="cm_n_n_n_3F7F7F">xml</span> <span class="cm_n_n_n_7F007F">version</span>=<span
class="cm_n_i_n_2A00FF">"1.0"</span> <span class="cm_n_n_n_7F007F">encoding</span>=<span
class="cm_n_i_n_2A00FF">"UTF-8"</span> <span class="cm_n_n_n_7F007F">standalone</span>=<span
class="cm_n_i_n_2A00FF">"no"</span><span class="cm_n_n_n_8080">?></span><br /> <span
class="cm_n_n_n_8080"><</span><span class="cm_n_n_n_3F7F7F">paletteDefinition</span><span class="cm_n_n_n_8080">></span><br />
<span class="cm_n_n_n_8080"><</span><span class="cm_n_n_n_3F7F7F">content</span><span
class="cm_n_n_n_8080">></span><br /> <span class="cm_n_n_n_8080"><</span><span
class="cm_n_n_n_3F7F7F">drawer</span> <span class="cm_n_n_n_7F007F">iconpath</span>=<span
class="cm_n_i_n_2A00FF">"/icons/drawer.gif"</span> <span class="cm_n_n_n_7F007F">id</span>=<span
class="cm_n_i_n_2A00FF">"UTP_Drawer"</span> <span class="cm_n_n_n_7F007F">name</span>=<span
class="cm_n_i_n_2A00FF">"UTP"</span><span class="cm_n_n_n_8080">></span><br />
<span class="cm_n_n_n_8080"><</span><span
class="cm_n_n_n_3F7F7F">aspectTool</span> <span class="cm_n_n_n_7F007F">description</span>=<span
class="cm_n_i_n_2A00FF">"Create a Test Context (Class)"</span><br />
<span
class="cm_n_n_n_7F007F">iconpath</span>=<span class="cm_n_i_n_2A00FF">"platform:/plugin/timezra.uml.testing.papyrus.palettes/icons/full/obj16/test_context_class.png"</span><br />
<span
class="cm_n_n_n_7F007F">id</span>=<span class="cm_n_i_n_2A00FF">"clazz.tool.class_UTP_TEST_CONTEXT"</span> <span
class="cm_n_n_n_7F007F">name</span>=<span class="cm_n_i_n_2A00FF">"Test Context (Class)"</span> <span
class="cm_n_n_n_7F007F">refToolId</span>=<span class="cm_n_i_n_2A00FF">"clazz.tool.class"</span><span
class="cm_n_n_n_8080">></span><br />
<span
class="cm_n_n_n_8080"><</span><span class="cm_n_n_n_3F7F7F">postAction</span> <span class="cm_n_n_n_7F007F">id</span>=<span
class="cm_n_i_n_2A00FF">"org.eclipse.papyrus.applystereotypeactionprovider"</span><span
class="cm_n_n_n_8080">></span><br />
<span
class="cm_n_n_n_8080"><</span><span class="cm_n_n_n_3F7F7F">stereotypesToApply</span><span class="cm_n_n_n_8080">></span><br />
<span
class="cm_n_n_n_8080"><</span><span class="cm_n_n_n_3F7F7F">stereotype</span> <span class="cm_n_n_n_7F007F">stereotypeName</span>=<span
class="cm_n_i_n_2A00FF">"utp::TestContext"</span> <span class="cm_n_n_n_8080">/></span><br />
<span
class="cm_n_n_n_8080"></</span><span class="cm_n_n_n_3F7F7F">stereotypesToApply</span><span class="cm_n_n_n_8080">></span><br />
<span
class="cm_n_n_n_8080"></</span><span class="cm_n_n_n_3F7F7F">postAction</span><span class="cm_n_n_n_8080">></span><br />
<span class="cm_n_n_n_8080"></</span><span
class="cm_n_n_n_3F7F7F">aspectTool</span><span class="cm_n_n_n_8080">></span><br />
<span class="cm_n_n_n_8080"></</span><span class="cm_n_n_n_3F7F7F">drawer</span><span
class="cm_n_n_n_8080">></span><br /> <span class="cm_n_n_n_8080"></</span><span
class="cm_n_n_n_3F7F7F">content</span><span class="cm_n_n_n_8080">></span><br /> <span class="cm_n_n_n_8080"></</span><span
class="cm_n_n_n_3F7F7F">paletteDefinition</span><span class="cm_n_n_n_8080">></span>
</div>
</body>
</html>
</div>
<br />
<p>Finally, we will register this palette configuration with a Papyrus extension.</p>
<em>plugin.xml</em>
<div>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Copy of plugin.xml</title>
<style type="text/css">
div.cm_source {
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin;
font-family: monospace;
font-size: 10pt;
white-space: nowrap;
}
span.cm_n_n_n_8080 {
color: #008080;
}
span.cm_n_n_n_3F7F7F {
color: #3F7F7F;
}
span.cm_n_n_n_7F007F {
color: #7F007F;
}
span.cm_n_i_n_2A00FF {
font-style: italic;
color: #2A00FF;
}
</style>
</head>
<body>
<div class="cm_source">
....<br /> <span class="cm_n_n_n_8080"><</span><span class="cm_n_n_n_3F7F7F">extension</span> <span
class="cm_n_n_n_7F007F">point</span>=<span class="cm_n_i_n_2A00FF">"org.eclipse.papyrus.uml.diagram.common.paletteDefinition"</span><span
class="cm_n_n_n_8080">></span><br /> <span class="cm_n_n_n_8080"><</span><span
class="cm_n_n_n_3F7F7F">paletteDefinition</span> <span class="cm_n_n_n_7F007F">ID</span>=<span
class="cm_n_i_n_2A00FF">"timezra.uml.testing.papyrus.palettes.UTP_clazz"</span><br />
<span class="cm_n_n_n_7F007F">class</span>=<span
class="cm_n_i_n_2A00FF">"org.eclipse.papyrus.uml.diagram.common.service.PluginPaletteProvider"</span><br />
<span class="cm_n_n_n_7F007F">icon</span>=<span
class="cm_n_i_n_2A00FF">"icons/full/obj16/utp_palette.png"</span> <span class="cm_n_n_n_7F007F">name</span>=<span
class="cm_n_i_n_2A00FF">"UTP Class Diagram Elements"</span><br />
<span class="cm_n_n_n_7F007F">path</span>=<span
class="cm_n_i_n_2A00FF">"palettes/UTP.clazz.palette.xml"</span><span class="cm_n_n_n_8080">></span><br />
<span class="cm_n_n_n_8080"><</span><span class="cm_n_n_n_3F7F7F">Priority</span> <span
class="cm_n_n_n_7F007F">name</span>=<span class="cm_n_i_n_2A00FF">"Medium"</span><span
class="cm_n_n_n_8080">></span><br /> <span class="cm_n_n_n_8080"></</span><span
class="cm_n_n_n_3F7F7F">Priority</span><span class="cm_n_n_n_8080">></span><br />
<span class="cm_n_n_n_8080"><</span><span class="cm_n_n_n_3F7F7F">editor</span> <span
class="cm_n_n_n_7F007F">id</span>=<span class="cm_n_i_n_2A00FF">"org.eclipse.papyrus.uml.diagram.clazz"</span><span
class="cm_n_n_n_8080">></span><br /> <span class="cm_n_n_n_8080"></</span><span
class="cm_n_n_n_3F7F7F">editor</span><span class="cm_n_n_n_8080">></span><br /> <span
class="cm_n_n_n_8080"></</span><span class="cm_n_n_n_3F7F7F">paletteDefinition</span><span class="cm_n_n_n_8080">></span><br />
<span class="cm_n_n_n_8080"></</span><span class="cm_n_n_n_3F7F7F">extension</span><span class="cm_n_n_n_8080">></span><br />
....
</div>
</body>
</html>
</div>
<br />
<p>
Once we register the palette definition with Papyrus, the test will pass and the TestContext contribution will be
visible for UML Models that have the UML Testing Profile applied. <img alt="TestContext palette contribution"
src="http://farm3.staticflickr.com/2925/14029917525_0c55965d1c_b.jpg" />
</p>
<h4>
<a id="Conclusion">Conclusion</a>
</h4>
<p>
In this article, we expose the following behaviors from the Eclipse workbench: the ability to apply the UML Testing
Profile within the UML and Papyrus Editors and the ability to create UML elements extended by UML stereotypes defined
in the UTP directly from a Papyrus editor palette. We describe these behaviors through tests and define them with
plug-in extensions and external configuration. The code for these examples is <a
href="https://github.com/timezra/UML-Testing-Tool/releases/tag/v1.0.0.PaletteDefinition">here</a>.
</p>
</body>
</html>
Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com13tag:blogger.com,1999:blog-106449775438946661.post-62655933710731647972014-02-24T01:20:00.001-08:002014-03-09T11:54:14.201-07:00Deleting Directories Whose Contents Have Long Names From C#Deleting Directories Whose Contents Have Long Names In C#
<h4>Goal:</h4>
<p>To use C# to delete directories that contain files whose fully qualified names are longer than 260 characters.</p>
<h4>Deleting a Directory That Contains Contents With Short Names</h4>
<p>Suppose we need to delete a directory and all its contents from C#. If the fully qualified names of all its contents are less than 260 characters, then the standard <em>DirectoryInfo.Delete</em> method is sufficient, as we can see from the following test case.</p>
<em>LongFileNamesTest.cs</em>
<div style="overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin;
white-space: nowrap;">
<span style="font-family: monospace; font-size: 10pt;">
<span style="color: #0000ff;">using</span> <span style="color: #000000;">Microsoft.VisualStudio.TestTools.UnitTesting;</span><br />
<span style="color: #0000ff;">using</span> <span style="color: #000000;">System.IO;</span><br />
<br />
<span style="color: #0000ff;">namespace</span> <span style="color: #000000;">Timezra.LongFileNames</span><br />
<span style="color: #000000;">{</span><br />
<span style="color: #000000;">[</span><span style="color: #2b91af;">TestClass</span><span style="color: #000000;">]</span><br />
<span style="color: #0000ff;">public</span><span style="color: #000000;"></span> <span style="color: #0000ff;">class</span><span style="color: #000000;"></span> <span style="color: #2b91af;">LongFileNamesTest</span><br />
<span style="color: #000000;">{</span><br />
<span style="color: #000000;">[</span><span style="color: #2b91af;">TestMethod</span><span style="color: #000000;">]</span><br />
<span style="color: #0000ff;">public</span><span style="color: #000000;"></span> <span style="color: #0000ff;">void</span> <span style="color: #000000;">ShouldDeleteALocalDirectoryWithContents()</span><br />
<span style="color: #000000;">{</span><br />
<span style="color: #0000ff;">var</span> <span style="color: #000000;">directory =</span> <span style="color: #2b91af;">Directory</span><span style="color: #000000;">.CreateDirectory(</span><span style="color: #2b91af;">Path</span><span style="color: #000000;">.Combine(</span><span style="color: #2b91af;">Path</span><span style="color: #000000;">.GetTempPath(),</span> <span style="color: #2b91af;">Path</span><span style="color: #000000;">.GetRandomFileName()));</span><br />
<span style="color: #0000ff;">var</span> <span style="color: #000000;">fileName = </span> <span style="color: #2b91af;">Path</span><span style="color: #000000;">.Combine(directory.FullName,</span> <span style="color: #2b91af;">Path</span><span style="color: #000000;">.GetRandomFileName());</span><br />
<span style="color: #000000;">System.IO.</span><span style="color: #2b91af;">File</span><span style="color: #000000;">.Create(fileName).Dispose();</span><br />
<br />
<span style="color: #000000;">directory.Delete(</span><span style="color: #0000ff;">true</span><span style="color: #000000;">);</span> <span style="color: #008000;">// Regular Directory Delete</span><br />
<br />
<span style="color: #2b91af;">Assert</span><span style="color: #000000;">.IsFalse(directory.Exists);</span><br />
<span style="color: #000000;">}</span><br />
<span style="color: #000000;">}</span><br />
<span style="color: #000000;">}</span><br />
</span>
</div>
<h4>Deleting a Directory That Contains Contents With Long Names</h4>
<p>Unfortunately, if the directory contains contents whose fully-qualified names are longer than 260 characters, this same method will fail.</p>
<em>LongFileNamesTest.cs</em>
<div style="overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin;
white-space: nowrap;">
<span style="font-family: monospace; font-size: 10pt;">
<span style="color: #000000;">[</span><span style="color: #2b91af;">TestMethod</span><span style="color: #000000;">]</span><br />
<span style="color: #0000ff;">public</span><span style="color: #000000;"></span> <span style="color: #0000ff;">void</span> <span style="color: #000000;">ShouldDeleteALocalDirectoryWithContentsThatHaveLongNames()</span><br />
<span style="color: #000000;">{</span><br />
<span style="color: #0000ff;">const int</span><span style="color: #000000;"> longFileNameLength = 247;</span><br />
<span style="color: #0000ff;">var</span><span style="color: #000000;"> directory =</span> <span style="color: #2b91af;">Directory</span><span style="color: #000000;">.CreateDirectory(</span><span style="color: #2b91af;">Path</span><span style="color: #000000;">.Combine(</span><span style="color: #2b91af;">Path</span><span style="color: #000000;">.GetTempPath(),</span> <span style="color: #2b91af;">Path</span><span style="color: #000000;">.GetRandomFileName()));</span><br />
<span style="color: #0000ff;">var</span><span style="color: #000000;"> fileName =</span> <span style="color: #2b91af;">Path</span><span style="color: #000000;">.Combine(directory.FullName,</span> <span style="color: #0000ff;">new string</span><span style="color: #000000;">(</span><span style="color: #a31515;">'z'</span><span style="color: #000000;">, longFileNameLength) +</span> <span style="color: #a31515;">".txt"</span><span style="color: #000000;">);</span><br />
<span style="color: #000000;">System.IO.</span><span style="color: #2b91af;">File</span><span style="color: #000000;">.Create(fileName).Dispose();</span><br />
<br />
<span style="color: #000000;">directory.Delete(</span><span style="color: #0000ff;">true</span><span style="color: #000000;">);</span> <span style="color: #008000;">// Regular Directory Delete</span><br />
<br />
<span style="color: #2b91af;">Assert</span><span style="color: #000000;">.IsFalse(directory.Exists);</span><br />
<span style="color: #000000;">}</span><br />
</span>
</div>
<br />
<p>This test case will fail with a message similar to this because we cannot even create the file with a fully-qualified name longer than 260 characters.</p>
<em>Test Failed - ShouldDeleteALocalDirectoryWithContentsThatHaveLongNames</em>
<div style="overflow: auto;
padding: 1em;
background-color: lightgray;
border-style: dashed;
border-width: thin;
white-space: nowrap;">
<span style="font-family: monospace; font-size: 10pt;">
<span style="font-weight: bold;">Result Message:</span><br />
<span style="font-weight: bold;">Test method Timezra.LongFileNames.LongFileNamesTest.ShouldDeleteALocalDirectoryWithContentsThatHaveLongNames threw exception:</span><br />
<span style="font-weight: bold;">System.IO.PathTooLongException: The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.</span><br />
Result StackTrace:<br />
at System.IO.PathHelper.GetFullPathName()<br />
at System.IO.Path.NormalizePath(String path, Boolean fullCheck, Int32 maxPathLength)<br />
at System.IO.FileStream.Init(String path, FileMode mode, FileAccess access, Int32 rights, Boolean useRights, FileShare share, Int32 bufferSize, FileOptions options, SECURITY_ATTRIBUTES secAttrs, String msgPath, Boolean bFromProxy, Boolean useLongPath, Boolean checkHost)<br />
at System.IO.FileStream..ctor(String path, FileMode mode, FileAccess access, FileShare share, Int32 bufferSize)<br />
at System.IO.File.Create(String path)<br />
at Timezra.LongFileNames.LongFileNamesTest.ShouldDeleteALocalDirectoryWithContentsThatHaveLongNames()<br />
</span>
</div>
<br />
<p>Even if we managed to create the file outside of the test case (say by extracting an archive that contains files with long names), then we would see a more cryptic error on delete.</p>
<em>Test Failed - ShouldDeleteALocalDirectoryWithContentsThatHaveLongNames</em>
<div style="overflow: auto;
padding: 1em;
background-color: lightgray;
border-style: dashed;
border-width: thin;
white-space: nowrap;">
<span style="font-family: monospace; font-size: 10pt;">
<span style="font-weight: bold;">Result Message:</span><br />
<span style="font-weight: bold;">Test method Timezra.LongFileNames.LongFileNamesTest.ShouldDeleteALocalDirectoryWithContentsThatHaveLongNames threw exception:</span><br />
<span style="font-weight: bold;">System.IO.DirectoryNotFoundException: Could not find a part of the path....</span><br />
Result StackTrace:<br />
at System.IO.Directory.DeleteHelper(String fullPath, String userPath, Boolean recursive, Boolean throwOnTopLevelDirectoryNotFound)<br />
at System.IO.Directory.Delete(String fullPath, String userPath, Boolean recursive, Boolean checkHost)<br />
at System.IO.DirectoryInfo.Delete(Boolean recursive)<br />
at Timezra.LongFileNames.LongFileNamesTest.ShouldDeleteALocalDirectoryWithContentsThatHaveLongNames()<br />
</span>
</div>
<br />
<p>We can get around this limit on creating and deleting long files by using the Microsoft Scripting Runtime and a special prefix on our file path.
First, our project needs a Reference to <strong>COM -> Microsoft Scripting Runtime</strong>.
Then we can use methods on the <em>FileSystemObject</em>, along with the <em>\\?\</em> prefix to our path.</p>
<em>LongFileNamesTest.cs</em>
<div style="overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin;
white-space: nowrap;">
<span style="font-family: monospace; font-size: 10pt;">
<span style="color: #000000;">[</span><span style="color: #2b91af;">TestMethod</span><span style="color: #000000;">]</span><br />
<span style="color: #0000ff;">public</span><span style="color: #000000;"></span> <span style="color: #0000ff;">void</span> <span style="color: #000000;">ShouldDeleteALocalDirectoryWithContentsThatHaveLongNames()</span><br />
<span style="color: #000000;">{</span><br />
<span style="color: #0000ff;">const int</span> <span style="color: #000000;">longFileNameLength = 247;</span><br />
<span style="color: #0000ff;">var</span> <span style="color: #000000;">directory =</span> <span style="color: #2b91af;">Directory</span><span style="color: #000000;">.CreateDirectory(</span><span style="color: #2b91af;">Path</span><span style="color: #000000;">.Combine(</span><span style="color: #2b91af;">Path</span><span style="color: #000000;">.GetTempPath(),</span> <span style="color: #2b91af;">Path</span><span style="color: #000000;">.GetRandomFileName()));</span><br />
<span style="color: #0000ff;">var</span> <span style="color: #000000;">fileName =</span> <span style="color: #2b91af;">Path</span><span style="color: #000000;">.Combine(directory.FullName,</span> <span style="color: #0000ff;">new string</span><span style="color: #000000;">(</span><span style="color: #a31515;">'z'</span><span style="color: #000000;">, longFileNameLength) +</span> <span style="color: #a31515;">".txt"</span><span style="color: #000000;">);</span><br />
<span style="color: #0000ff;">var</span> <span style="color: #000000;">fso =</span> <span style="color: #0000ff;">new</span> <span style="color: #000000;">Scripting.</span><span style="color: #2b91af;">FileSystemObject</span><span style="color: #000000;">();</span><br />
<span style="color: #000000;">fso.CreateTextFile(</span><span style="color: #a31515;">@"\\?\"</span> <span style="color: #000000;">+ fileName).Close();</span><br />
<br />
<span style="color: #000000;">fso.DeleteFolder(</span><span style="color: #a31515;">@"\\?\"</span> <span style="color: #000000;">+ directory.FullName,</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">);</span> <span style="color: #008000;">// Local Directory Delete When Contents Have Long Names</span><br />
<br />
<span style="color: #2b91af;">Assert</span><span style="color: #000000;">.IsFalse(directory.Exists);</span><br />
<span style="color: #000000;">}</span><br />
</span>
</div>
<h4>Deleting a Remote Directory That Contains Contents With Long Names</h4>
<p>Suppose we also need to support the deletion of remote directories with contents that are longer than 260 characters. The same principle applies, but our prefix is slightly different, i.e., <em>\\?\UNC</em>. Fortunately, we can test this by converting our local directory path to a UNC directory path.</p>
<em>LongFileNamesTest.cs</em>
<div style="overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin;
white-space: nowrap;">
<span style="font-family: monospace; font-size: 10pt;">
<span style="color: #000000;">[</span><span style="color: #2b91af;">TestMethod</span><span style="color: #000000;">]</span><br />
<span style="color: #0000ff;">public</span><span style="color: #000000;"></span> <span style="color: #0000ff;">void</span> <span style="color: #000000;">ShouldDeleteARemoteDirectoryWithContentsThatHaveLongNames()</span><br />
<span style="color: #000000;">{</span><br />
<span style="color: #0000ff;">const int</span> <span style="color: #000000;">longFileNameLength = 247;</span><br />
<span style="color: #0000ff;">var</span> <span style="color: #000000;">directory =</span> <span style="color: #2b91af;">Directory</span><span style="color: #000000;">.CreateDirectory(</span><span style="color: #2b91af;">Path</span><span style="color: #000000;">.Combine(</span><span style="color: #2b91af;">Path</span><span style="color: #000000;">.GetTempPath(),</span> <span style="color: #2b91af;">Path</span><span style="color: #000000;">.GetRandomFileName()));</span><br />
<span style="color: #0000ff;">var</span> <span style="color: #000000;">fileName =</span> <span style="color: #2b91af;">Path</span><span style="color: #000000;">.Combine(directory.FullName,</span> <span style="color: #0000ff;">new string</span><span style="color: #000000;">(</span><span style="color: #a31515;">'z'</span><span style="color: #000000;">, longFileNameLength) +</span> <span style="color: #a31515;">".txt"</span><span style="color: #000000;">);</span><br />
<span style="color: #0000ff;">var</span> <span style="color: #000000;">fso =</span> <span style="color: #0000ff;">new</span> <span style="color: #000000;">Scripting.</span><span style="color: #2b91af;">FileSystemObject</span><span style="color: #000000;">();</span><br />
<span style="color: #000000;">fso.CreateTextFile(</span><span style="color: #a31515;">@"\\?\"</span> <span style="color: #000000;">+ fileName).Close();</span><br />
<br />
<span style="color: #0000ff;">var</span> <span style="color: #000000;">uncDirectoryName =</span> <span style="color: #a31515;">@"\\"</span> <span style="color: #000000;">+ System.</span><span style="color: #2b91af;">Environment</span><span style="color: #000000;">.MachineName +</span> <span style="color: #a31515;">@"\"</span> <span style="color: #000000;">+ directory.FullName.Replace(</span><span style="color: #a31515;">':'</span><span style="color: #000000;">,</span> <span style="color: #a31515;">'$'</span><span style="color: #000000;">);</span><br />
<span style="color: #000000;">fso.DeleteFolder(</span><span style="color: #a31515;">@"\\?\UNC"</span> <span style="color: #000000;">+ uncDirectoryName.Substring(1),</span> <span style="color: #0000ff;">true</span><span style="color: #000000;">);</span> <span style="color: #008000;">// Remote Directory Delete When Contents Have Long Names</span><br />
<br />
<span style="color: #2b91af;">Assert</span><span style="color: #000000;">.IsFalse(directory.Exists);</span><br />
<span style="color: #000000;">}</span><br />
</span>
</div>
Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com1tag:blogger.com,1999:blog-106449775438946661.post-89276281147736230942013-10-16T01:58:00.000-07:002013-10-16T01:58:10.903-07:00JaCoCo and Scala<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>JaCoCo and Scala</title>
</head>
<body>
<h4>Goal</h4>
<p>To generate a reasonably accurate JaCoCo code coverage report for a Scala project.</p>
<h4>tl;dr</h4>
<p>A Maven plug-in for creating <a href="http://www.eclemma.org/jacoco/">JaCoCo</a> code coverage reports is <a href="https://github.com/timezra/jacoco-scala-maven-plugin">available on github</a> and will be a helpful resource for following this article. This project contains <a href="https://github.com/timezra/jacoco-scala-maven-plugin/tree/master/jacoco-scalatest-maven-plugin-example">an example</a> that integrates <a href="http://maven.apache.org/">Maven</a>, <a href="http://www.eclemma.org/jacoco/">JaCoCo</a> and <a href="http://www.scalatest.org/">ScalaTest</a> with <a href="https://github.com/timezra/jacoco-scala-maven-plugin">this plug-in</a> and can be used as a template for your own projects. The interesting technologies showcased include <a href="http://www.eclemma.org/jacoco/">JaCoCo</a> and <a href="http://www.scala-lang.org/">Scala</a>.
</p>
<h4><a id="the_project">The Project</a></h4>
<p>Suppose our development team would like to track how much of our Scala code is covered by our test suite. Now suppose we would like to configure Maven to generate these reports with each build.
</p>
<h4><a id="using_the_jacoco_maven_plugin">Using The Jacoco Maven Plug-in</a></h4>
<p>The <a href="http://www.eclemma.org/jacoco/trunk/doc/maven.html">JaCoCo Maven plug-in</a> can easily be configured to record and report coverage metrics for compiled Scala because <a href="http://www.eclemma.org/jacoco/trunk/doc/agent.html">JaCoCo uses a java agent to instrument bytecode on the fly</a>. For example, given a project with standard layout, where <em>Example.scala</em> and <em>ExampleSpec.scala</em> represent a worker and its ScalaTest specification, then the pom configuration is fairly straightforward.
</p>
<p>
<em>The project layout</em>
<div style="overflow: auto;
padding: 1em;
background-color: black;
color: white;
border-style: dashed;
border-width: thin">
<span style="font-family: courier new; font-size: 11pt;"><br />
jacoco-scalatest-maven-plugin-example<br />
.<br />
|____pom.xml<br />
| src<br />
| | main<br />
| | | scala<br />
| | |____Example.scala<br />
| src<br />
| | test<br />
| | | scala<br />
| | |____ExampleSpec.scala<br />
</span><br />
</div>
</p>
<p>
<em>pom.xml</em>
<div style="overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin;
height: 350px">
<span style="font-family: monospace; font-size: 10pt;">
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0"</span> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span><br />
<span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span>4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>timezra.maven<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>jacoco-scalatest-maven-plugin-example<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>0.6.3.2-SNAPSHOT<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br />
<br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">properties</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project.build.sourceEncoding</span><span style="color: rgb(0,128,128);">></span>UTF-8<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project.build.sourceEncoding</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">properties</span><span style="color: rgb(0,128,128);">></span><br />
<br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.scala-lang<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>scala-library<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.10.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.scalatest<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>scalatest_2.10<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.0.RC2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br />
<br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">sourceDirectory</span><span style="color: rgb(0,128,128);">></span>src/main/scala<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">sourceDirectory</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">testSourceDirectory</span><span style="color: rgb(0,128,128);">></span>src/test/scala<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">testSourceDirectory</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.scala-tools<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>maven-scala-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.15.2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span>compile<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span>testCompile<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.jacoco<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>jacoco-maven-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>0.6.3.201306030806<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>pre-test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span>prepare-agent<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>post-integration-test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span>post-integration-test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span>report<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.apache.maven.plugins<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>maven-surefire-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.16<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">skipTests</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">skipTests</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.scalatest<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>scalatest-maven-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.0-RC1<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">reportsDirectory</span><span style="color: rgb(0,128,128);">></span>${project.build.directory}/surefire-reports<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">reportsDirectory</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">junitxml</span><span style="color: rgb(0,128,128);">></span>.<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">junitxml</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span>integration-test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span><br />
</span>
</div>
</p>
<h4><a id="mix_ins">Traits and Mixed-in Methods</a></h4>
<p>Unfortunately, this configuration will soon begin reporting false negative results when even the most basic Scala features are employed. For example, suppose our Example class extends a Scala trait.
</p>
<p>
<em>ExampleTrait.scala</em>
<div style="overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin">
<span style="font-family: monospace; font-size: 10pt;">
<span style="font-weight: bold; color: rgb(151,44,120);">trait</span> ExampleTrait {<br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> thisIsMixedIn() {<br />
println(<span style="color: rgb(42,0,255);">"Hello world"</span>)<br />
}<br />
}<br />
</span>
</div>
</p>
<p>
<em>TraitExample.scala</em>
<div style="overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin">
<span style="font-family: monospace; font-size: 10pt;">
<span style="font-weight: bold; color: rgb(151,44,120);">class</span> TraitExample <span style="font-weight: bold; color: rgb(151,44,120);">extends</span> ExampleTrait {<br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> sayHello() {<br />
println(<span style="color: rgb(42,0,255);">"Hello world"</span>)<br />
}<br />
}<br />
</span>
</div>
</p>
<p>
<em>ExampleSpec.scala</em>
<div style="overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin">
<span style="font-family: monospace; font-size: 10pt;">
<span style="font-weight: bold; color: rgb(151,44,120);">import</span> org.scalatest.FunSpec<br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">class</span> ExampleSpec <span style="font-weight: bold; color: rgb(151,44,120);">extends</span> FunSpec {<br />
describe(<span style="color: rgb(42,0,255);">"A Canary"</span>) {<br />
it(<span style="color: rgb(42,0,255);">"should cover a class that mixes in a trait"</span>) {<br />
<span style="font-weight: bold; color: rgb(151,44,120);">val</span> traitExample = <span style="font-weight: bold; color: rgb(151,44,120);">new</span> TraitExample<br />
traitExample.sayHello<br />
}<br />
}<br />
}<br />
</span>
</div>
</p>
<p>
The coverage results show a false negative result for the mixed-in method <em>ExampleTrait#thisIsMixedIn</em>. We expect to see 100% coverage but instead see 75%.<br />
<img alt="The coverage results for the TraitExample include a false negative report for the method mixed-in from the ExampleTrait." src="http://farm6.staticflickr.com/5495/10305322395_f09fd138d2_z.jpg" />
</p>
<p>
We can see from the bytecode for <em>ExampleTrait</em> that the Scala compiler mixes in traits by generating bytecode for methods in the extending classes and these generated methods delegate to the implemented traits via static calls.<br />
<div style="overflow: auto;
padding: 1em;
background-color: lightgray;
border-style: dashed;
border-width: thin;">
<span style="font-family: monospace; font-size: 10pt;">
public class TraitExample implements ExampleTrait {<br />
public void thisIsMixedIn();<br />
0 aload_0 [this]<br />
1 <span style="color: rgb(34,139,34);">invokestatic ExampleTrait$class.thisIsMixedIn(ExampleTrait)</span> : void [17]<br />
4 return<br />
Line numbers:<br />
[pc: 0, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">22</span>]<br />
Local variable table:<br />
[pc: 0, pc: 5] local: this index: 0 type: TraitExample<br />
<br />
....<br />
<br />
public TraitExample();<br />
0 aload_0 [this]<br />
1 invokespecial java.lang.Object() [35]<br />
4 aload_0 [this]<br />
5 invokestatic ExampleTrait$class.$init$(ExampleTrait) : void [38]<br />
8 return<br />
Line numbers:<br />
[pc: 0, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">22</span>]<br />
Local variable table:<br />
[pc: 0, pc: 9] local: this index: 0 type: TraitExample<br />
}<br />
</span>
</div>
</p>
<p>
We can also see from the bytecode that the line numbers for the mixed-in method and the constructor are the same. Perhaps this coincidence can give us enough information to filter out these types of false negatives from our coverage report.
</p>
<h4><a id="case_classes">Case Classes</a></h4>
<p>Similarly, case classes generate even more bytecode for methods that can be excluded from our coverage reports.
</p>
<p>
<em>CaseExample.scala</em>
<div style="overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin">
<span style="font-family: monospace; font-size: 10pt;">
<span style="font-weight: bold; color: rgb(151,44,120);">case class</span> CaseExample(<br />
<span style="color: rgb(42,0,255);">greeting</span>: String = <span style="color: rgb(42,0,255);">"Hello"</span>,<br />
<span style="color: rgb(42,0,255);">name</span>: String = <span style="color: rgb(42,0,255);">"world"</span>) {<br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> sayHello() {<br />
println(s<span style="color: rgb(42,0,255);">"$</span>{<span style="color: rgb(42,0,255);">greeting</span>} <span style="color: rgb(42,0,255);">$</span>{<span style="color: rgb(42,0,255);">name</span>}<span style="color: rgb(42,0,255);">"</span>)<br />
}<br />
}<br />
</span>
</div>
</p>
<p>
<em>ExampleSpec.scala</em>
<div style="overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin">
<span style="font-family: monospace; font-size: 10pt;">
<span style="font-weight: bold; color: rgb(151,44,120);">import</span> org.scalatest.FunSpec<br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">class</span> ExampleSpec <span style="font-weight: bold; color: rgb(151,44,120);">extends</span> FunSpec {<br />
describe(<span style="color: rgb(42,0,255);">"A Canary"</span>) {<br />
it(<span style="color: rgb(42,0,255);">"should cover a case class"</span>) {<br />
<span style="font-weight: bold; color: rgb(151,44,120);">val</span> caseExample = <span style="font-weight: bold; color: rgb(151,44,120);">new</span> CaseExample<br />
caseExample.sayHello<br />
}<br />
}<br />
}<br />
</span>
</div>
</p>
<p>
The coverage results show significantly more false negative results for mixed-in and generated methods. We expect to see coverage results closer to 100% than to 32%.<br />
<img alt="The coverage results for the CaseExample include false negative reports for mixed-in and generated methods." src="http://farm8.staticflickr.com/7331/10305945113_5c1f85c368_z.jpg" />
</p>
<p>
Again, we can see from the bytecode that the line numbers for the mixed-in methods and the constructor are the same. We can also see from the bytecode that generated methods follow a pattern: <em>curried()</em>, <em>tupled()</em> and <em>(\w|\$)+\$default\$\d+\(\)</em> methods. These methods unfortunately cannot be filtered by their debug line numbers, but they can be identified consistently by name. This information may be sufficient for eliminating these false negative results so that our coverage trend can at least look more reasonable even if not exact.<br />
<div style="overflow: auto;
padding: 1em;
background-color: lightgray;
border-style: dashed;
border-width: thin;
height: 250px">
<span style="font-family: monospace; font-size: 10pt;">
public class CaseExample implements scala.Product, scala.Serializable {<br />
private final java.lang.String greeting;<br />
private final java.lang.String name;<br />
<br />
public static java.lang.String apply$default$2();<br />
0 getstatic CaseExample$.MODULE$ : CaseExample. [20]<br />
3 invokevirtual CaseExample$.apply$default$2() : java.lang.String [22]<br />
6 areturn<br />
<br />
public static java.lang.String apply$default$1();<br />
0 getstatic CaseExample$.MODULE$ : CaseExample. [20]<br />
3 invokevirtual CaseExample$.apply$default$1() : java.lang.String [25]<br />
6 areturn<br />
<br />
public static java.lang.String $lessinit$greater$default$2();<br />
0 getstatic CaseExample$.MODULE$ : CaseExample. [20]<br />
3 invokevirtual CaseExample$.$lessinit$greater$default$2() : java.lang.String [28]<br />
6 areturn<br />
<br />
public static java.lang.String $lessinit$greater$default$1();<br />
0 getstatic CaseExample$.MODULE$ : CaseExample. [20]<br />
3 invokevirtual CaseExample$.$lessinit$greater$default$1() : java.lang.String [31]<br />
6 areturn<br />
<br />
public static scala.Function1 tupled();<br />
0 getstatic CaseExample$.MODULE$ : CaseExample. [20]<br />
3 invokevirtual CaseExample$.tupled() : scala.Function1 [35]<br />
6 areturn<br />
<br />
public static scala.Function1 curried();<br />
0 getstatic CaseExample$.MODULE$ : CaseExample. [20]<br />
3 invokevirtual CaseExample$.curried() : scala.Function1 [38]<br />
6 areturn<br />
<br />
public java.lang.String greeting();<br />
0 aload_0 [this]<br />
1 getfield CaseExample.greeting : java.lang.String [43]<br />
4 areturn<br />
Line numbers:<br />
[pc: 0, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">23</span>]<br />
Local variable table:<br />
[pc: 0, pc: 5] local: this index: 0 type: CaseExample<br />
<br />
public java.lang.String name();<br />
0 aload_0 [this]<br />
1 getfield CaseExample.name : java.lang.String [47]<br />
4 areturn<br />
Line numbers:<br />
[pc: 0, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">24</span>]<br />
Local variable table:<br />
[pc: 0, pc: 5] local: this index: 0 type: CaseExample<br />
<br />
.... <br />
<br />
public CaseExample copy(java.lang.String greeting, java.lang.String name);<br />
0 new CaseExample [2]<br />
3 dup<br />
4 aload_1 [greeting]<br />
5 aload_2 [name]<br />
6 invokespecial CaseExample(java.lang.String, java.lang.String) [95]<br />
9 areturn<br />
Line numbers:<br />
[pc: 0, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">22</span>]<br />
[pc: 4, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">23</span>]<br />
[pc: 5, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">24</span>]<br />
[pc: 6, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">22</span>]<br />
Local variable table:<br />
[pc: 0, pc: 10] local: this index: 0 type: CaseExample<br />
[pc: 0, pc: 10] local: greeting index: 1 type: java.lang.String<br />
[pc: 0, pc: 10] local: name index: 2 type: java.lang.String<br />
<br />
public java.lang.String copy$default$1();<br />
0 aload_0 [this]<br />
1 invokevirtual CaseExample.greeting() : java.lang.String [76]<br />
4 areturn<br />
Line numbers:<br />
[pc: 0, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">23</span>]<br />
Local variable table:<br />
[pc: 0, pc: 5] local: this index: 0 type: CaseExample<br />
<br />
public java.lang.String copy$default$2();<br />
0 aload_0 [this]<br />
1 invokevirtual CaseExample.name() : java.lang.String [78]<br />
4 areturn<br />
Line numbers:<br />
[pc: 0, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">24</span>]<br />
Local variable table:<br />
[pc: 0, pc: 5] local: this index: 0 type: CaseExample<br />
<br />
public java.lang.String productPrefix();<br />
0 ldc <String "CaseExample"> [99]<br />
2 areturn<br />
Line numbers:<br />
[pc: 0, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">22</span>]<br />
Local variable table:<br />
[pc: 0, pc: 3] local: this index: 0 type: CaseExample<br />
<br />
public int productArity();<br />
0 iconst_2<br />
1 ireturn<br />
Line numbers:<br />
[pc: 0, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">22</span>]<br />
Local variable table:<br />
[pc: 0, pc: 2] local: this index: 0 type: CaseExample<br />
<br />
public java.lang.Object productElement(int x$1);<br />
0 iload_1 [x$1]<br />
1 istore_2<br />
2 iload_2<br />
3 tableswitch default: 24<br />
case 0: 46<br />
case 1: 39<br />
24 new java.lang.IndexOutOfBoundsException [105]<br />
27 dup<br />
28 iload_1 [x$1]<br />
29 invokestatic scala.runtime.BoxesRunTime.boxToInteger(int) : java.lang.Integer [111]<br />
32 invokevirtual java.lang.Object.toString() : java.lang.String [114]<br />
35 invokespecial java.lang.IndexOutOfBoundsException(java.lang.String) [117]<br />
38 athrow<br />
39 aload_0 [this]<br />
40 invokevirtual CaseExample.name() : java.lang.String [78]<br />
43 goto 50<br />
46 aload_0 [this]<br />
47 invokevirtual CaseExample.greeting() : java.lang.String [76]<br />
50 areturn<br />
Line numbers:<br />
[pc: 0, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">22</span>]<br />
Local variable table:<br />
[pc: 0, pc: 51] local: this index: 0 type: CaseExample<br />
[pc: 0, pc: 51] local: x$1 index: 1 type: int<br />
Stack map table: number of frames 4<br />
[pc: 24, append: {int}]<br />
[pc: 39, same]<br />
[pc: 46, same]<br />
[pc: 50, same_locals_1_stack_item, stack: {java.lang.String}]<br />
<br />
public scala.collection.Iterator productIterator();<br />
0 getstatic scala.runtime.ScalaRunTime$.MODULE$ : scala.runtime.ScalaRunTime. [126]<br />
3 aload_0 [this]<br />
4 invokevirtual scala.runtime.ScalaRunTime$.typedProductIterator(scala.Product) : scala.collection.Iterator [130]<br />
7 areturn<br />
Line numbers:<br />
[pc: 0, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">22</span>]<br />
Local variable table:<br />
[pc: 0, pc: 8] local: this index: 0 type: CaseExample<br />
<br />
public boolean canEqual(java.lang.Object x$1);<br />
0 aload_1 [x$1]<br />
1 instanceof CaseExample [2]<br />
4 ireturn<br />
Line numbers:<br />
[pc: 0, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">22</span>]<br />
Local variable table:<br />
[pc: 0, pc: 5] local: this index: 0 type: CaseExample<br />
[pc: 0, pc: 5] local: x$1 index: 1 type: java.lang.Object<br />
<br />
public int hashCode();<br />
0 getstatic scala.runtime.ScalaRunTime$.MODULE$ : scala.runtime.ScalaRunTime. [126]<br />
3 aload_0 [this]<br />
4 invokevirtual scala.runtime.ScalaRunTime$._hashCode(scala.Product) : int [138]<br />
7 ireturn<br />
Line numbers:<br />
[pc: 0, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">22</span>]<br />
Local variable table:<br />
[pc: 0, pc: 8] local: this index: 0 type: CaseExample<br />
<br />
public java.lang.String toString();<br />
0 getstatic scala.runtime.ScalaRunTime$.MODULE$ : scala.runtime.ScalaRunTime. [126]<br />
3 aload_0 [this]<br />
4 invokevirtual scala.runtime.ScalaRunTime$._toString(scala.Product) : java.lang.String [142]<br />
7 areturn<br />
Line numbers:<br />
[pc: 0, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">22</span>]<br />
Local variable table:<br />
[pc: 0, pc: 8] local: this index: 0 type: CaseExample<br />
<br />
public boolean equals(java.lang.Object x$1);<br />
0 aload_0 [this]<br />
1 aload_1 [x$1]<br />
2 if_acmpeq 92<br />
5 aload_1 [x$1]<br />
6 instanceof CaseExample [2]<br />
9 ifeq 96<br />
12 aload_1 [x$1]<br />
13 checkcast CaseExample [2]<br />
16 astore_2<br />
17 aload_0 [this]<br />
18 invokevirtual CaseExample.greeting() : java.lang.String [76]<br />
21 aload_2<br />
22 invokevirtual CaseExample.greeting() : java.lang.String [76]<br />
25 astore_3<br />
26 dup<br />
27 ifnonnull 38<br />
30 pop<br />
31 aload_3<br />
32 ifnull 45<br />
35 goto 88<br />
38 aload_3<br />
39 invokevirtual java.lang.Object.equals(java.lang.Object) : boolean [145]<br />
42 ifeq 88<br />
45 aload_0 [this]<br />
46 invokevirtual CaseExample.name() : java.lang.String [78]<br />
49 aload_2<br />
50 invokevirtual CaseExample.name() : java.lang.String [78]<br />
53 astore 4<br />
55 dup<br />
56 ifnonnull 68<br />
59 pop<br />
60 aload 4<br />
62 ifnull 76<br />
65 goto 88<br />
68 aload 4<br />
70 invokevirtual java.lang.Object.equals(java.lang.Object) : boolean [145]<br />
73 ifeq 88<br />
76 aload_2<br />
77 aload_0 [this]<br />
78 invokevirtual CaseExample.canEqual(java.lang.Object) : boolean [147]<br />
81 ifeq 88<br />
84 iconst_1<br />
85 goto 89<br />
88 iconst_0<br />
89 ifeq 96<br />
92 iconst_1<br />
93 goto 97<br />
96 iconst_0<br />
97 ireturn<br />
Line numbers:<br />
[pc: 0, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">22</span>]<br />
Local variable table:<br />
[pc: 0, pc: 98] local: this index: 0 type: CaseExample<br />
[pc: 0, pc: 98] local: x$1 index: 1 type: java.lang.Object<br />
Stack map table: number of frames 9<br />
[pc: 38, full, stack: {java.lang.String}, locals: {CaseExample, java.lang.Object, CaseExample, java.lang.String}]<br />
[pc: 45, same]<br />
[pc: 68, full, stack: {java.lang.String}, locals: {CaseExample, java.lang.Object, CaseExample, java.lang.String, java.lang.String}]<br />
[pc: 76, same]<br />
[pc: 88, chop 1 local(s)]<br />
[pc: 89, same_locals_1_stack_item, stack: {int}]<br />
[pc: 92, chop 2 local(s)]<br />
[pc: 96, same]<br />
[pc: 97, same_locals_1_stack_item, stack: {int}]<br />
<br />
public CaseExample(java.lang.String greeting, java.lang.String name);<br />
0 aload_0 [this]<br />
1 aload_1 [greeting]<br />
2 putfield CaseExample.greeting : java.lang.String [43]<br />
5 aload_0 [this]<br />
6 aload_2 [name]<br />
7 putfield CaseExample.name : java.lang.String [47]<br />
10 aload_0 [this]<br />
11 invokespecial java.lang.Object() [149]<br />
14 aload_0 [this]<br />
15 invokestatic scala.Product$class.$init$(scala.Product) : void [155]<br />
18 return<br />
Line numbers:<br />
[pc: 0, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">23</span>]<br />
[pc: 5, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">24</span>]<br />
[pc: 10, <span style="color: rgb(0,0,255);">line</span>: <span style="color: rgb(255,0,0);">22</span>]<br />
Local variable table:<br />
[pc: 0, pc: 19] local: this index: 0 type: CaseExample<br />
[pc: 0, pc: 19] local: greeting index: 1 type: java.lang.String<br />
[pc: 0, pc: 19] local: name index: 2 type: java.lang.String<br />
}<br />
</span>
</div>
</p>
<h4><a id="jacoco_scala_maven_plugin">JaCoCo Scala Maven Plugin</a></h4>
<p>The JaCoCo project maintainers are currently in the process of <a href="https://github.com/jacoco/jacoco/wiki/FilteringOptions"> collecting use cases</a> for the types of configurable filtering options that the community needs. Until that general-purpose solution has been implemented, the <a href="https://github.com/timezra/jacoco-scala-maven-plugin">jacoco-scala-maven-plugin</a> can be used to fulfill two of those specific filtering needs, i.e., <a href="https://github.com/jacoco/jacoco/wiki/filtering-SCALAC.MIXIN">SCALAC.MIXIN</a> and <a href="https://github.com/jacoco/jacoco/wiki/filtering-SCALAC.CASE">SCALAC.CASE</a>. These two filters eliminate methods that have the same debug line numbers as the constructor and the names <em>tupled()</em>, <em>curried()</em> and <em>(\w|\$)+\$default\$\d+\(\)</em>, as noted above.
</p>
<p>In our pom, instead of configuring the jacoco-maven-plugin to emit a report, we can now pass these two filtering options to the jacoco-scala-maven-plugin.<br />
<em>pom.xml</em>
<div style="overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin">
<span style="font-family: monospace; font-size: 10pt;">
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> ....<span style="color: rgb(0,128,128);">></span><br />
....<br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br />
....<br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br />
....<br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.jacoco<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>jacoco-maven-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>0.6.3.201306030806<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>pre-test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span>prepare-agent<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>timezra.maven<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>jacoco-scala-maven-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>0.6.3.1<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>post-integration-test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span>post-integration-test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span>report<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">filters</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">filter</span><span style="color: rgb(0,128,128);">></span>SCALAC.CASE<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">filter</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">filter</span><span style="color: rgb(0,128,128);">></span>SCALAC.MIXIN<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">filter</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">filters</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br />
....<br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">pluginRepositories</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">pluginRepository</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>tims-repo<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://timezra.github.com/maven/releases<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">releases</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">enabled</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">enabled</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">releases</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">snapshots</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">enabled</span><span style="color: rgb(0,128,128);">></span>false<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">enabled</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">snapshots</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">pluginRepository</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">pluginRepositories</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span><br />
</span>
</div>
</p>
<p>
When using these two filters, the coverage results for the <em>TraitExample</em> and <em>CaseExample</em> no longer include generated and mixed-in methods, and instead give us a more accurate coverage score of 100% for both.<br />
<img alt="The TraitExample coverage report without false negatives." src="http://farm8.staticflickr.com/7396/10306317755_cc57cd2327_z.jpg" /><br />
<img alt="The CaseExample coverage report without false negatives." src="http://farm8.staticflickr.com/7448/10306261274_b24468b2b4_z.jpg" />
</p>
<h4>Conclusion</h4>
<p>By examining and resolving anomalies in the code coverage statistics for our project through the introduction of a <a href="https://github.com/timezra/jacoco-scala-maven-plugin">jacoco-scala-maven-plugin</a>, we have gained an insight into how the Scala compiler mixes and injects methods into generated bytecode (which can also give insight into how Scala is able to chain <em>super</em> calls when multiple traits are linearized). While there are certainly other generated instructions that can be ignored during a coverage run, these two filters get us closer to being able to gather useful coverage trend information over time.
<p>If you notice any other filtering options that you would like to see from the <a href="https://github.com/timezra/jacoco-scala-maven-plugin">jacoco-scala-maven-plugin</a>, please let me know, either here or on <a href="https://github.com/timezra">github</a>.
</p>
</body>
</html>
Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com7tag:blogger.com,1999:blog-106449775438946661.post-44632947883767458632013-10-15T01:17:00.000-07:002013-10-15T23:01:08.856-07:00Cucumber and Maven<html>
<head>
<title>Cucumber and Maven</title>
</head>
<body>
<h4>
Goal</h4>
To run Cucumber specifications via Maven.<br />
<h4>
tl;dr</h4>
A maven plug-in for running Cucumber features via Cucumber-JVM is <a href="https://github.com/timezra/cucumber-jvm-maven-plugin">available on github</a> and will be a helpful resource for following this article. There is also a <a href="https://github.com/timezra/cucumber-jvm-archetype">maven archetype</a> for generating a <a href="https://github.com/cucumber/cucumber-jvm">Cucumber-JVM project</a>. Acceptance tests for the <a href="https://github.com/timezra/dropbox-maven-plugin">dropbox-maven-plugin</a> and <a href="https://github.com/timezra/jacoco-scala-maven-plugin">jacoco-scala-maven-plugin</a> both run using <a href="https://github.com/timezra/cucumber-jvm-maven-plugin">this plugin</a> and can be used as templates for your own specifications. The interesting technologies showcased include <a href="https://github.com/cucumber/cucumber-jvm">Cucumber-JVM</a> and <a href="http://jruby.org/">JRuby</a>.
<br />
<h4>
<a href="" id="the_project">The Project</a></h4>
Suppose our product owner would like to specify the behavior of our product in a way that can be verified automatically and continuously, for example, using <a href="https://github.com/cucumber/cucumber/wiki/Gherkin">Gherkin</a>. Now suppose we would like to configure a Maven build system to run these acceptance tests.
<br />
<h4>
<a href="" id="using_ant_runner">Using Ant Runner</a></h4>
The <a href="http://maven.apache.org/plugins/maven-antrun-plugin">maven-antrun-plugin</a> can often be the fallback when there is no maven plug-in for a specific purpose. Indeed there are <a href="https://github.com/cucumber/cucumber-jvm/tree/master/jruby">instructions</a> and <a href="https://github.com/dkowis/Cucumber-JVM-Ruby-Example">examples</a> of using the <a href="http://maven.apache.org/plugins/maven-antrun-plugin">maven-antrun-plugin</a> to spawn the command-line versions of both JRuby and Cucumber-JVM for initializing a Cucumber project, installing its required bundles and executing its specifications.
<br />
A project with a Gemfile in its root, features in its <em>src/test/features</em> directory and Ruby step definitions in its <em>src/test/features/step_definitions</em> directory can use a pom configuration like this to install and run its acceptance tests.<br />
<em>The project layout</em>
<div style="background-color: black; border-style: dashed; border-width: thin; color: white; overflow: auto; padding: 1em;">
<span style="font-family: courier new; font-size: 11pt;"><br />
my-cucumber-jvm-specifications<br />
.<br />
|____Gemfile<br />
|____pom.xml<br />
| src<br />
| | test<br />
| | | features<br />
| | |____my.feature<br />
| | | | step_definitions<br />
| | | |____my_steps.rb<br />
</span><br />
</div>
<br />
<em>pom.xml</em>
<div style="background-color: white; border-style: dashed; border-width: thin; height: 350px; overflow: auto; padding: 1em;">
<div style="font-family: courier new; font-size: 10pt;">
<span style="color: teal;"><</span><span style="color: #3f7f7f;">project</span> <span style="color: #7f007f;">xmlns</span>=<span style="color: #2a00ff; font-style: italic;">"http://maven.apache.org/POM/4.0.0"</span> <span style="color: #7f007f;">xmlns:xsi</span>=<span style="color: #2a00ff; font-style: italic;">"http://www.w3.org/2001/XMLSchema-instance"</span><br />
<span style="color: #7f007f;">xsi:schemaLocation</span>=<span style="color: #2a00ff; font-style: italic;">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">modelVersion</span><span style="color: teal;">></span>4.0.0<span style="color: teal;"></</span><span style="color: #3f7f7f;">modelVersion</span><span style="color: teal;">></span><br />
<br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">groupId</span><span style="color: teal;">></span>timezra.maven<span style="color: teal;"></</span><span style="color: #3f7f7f;">groupId</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">artifactId</span><span style="color: teal;">></span>cucumber-jvm-from-ant<span style="color: teal;"></</span><span style="color: #3f7f7f;">artifactId</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">version</span><span style="color: teal;">></span>1.0.0-SNAPSHOT<span style="color: teal;"></</span><span style="color: #3f7f7f;">version</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">name</span><span style="color: teal;">></span>cucumber-jvm-from-ant<span style="color: teal;"></</span><span style="color: #3f7f7f;">name</span><span style="color: teal;">></span><br />
<br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">properties</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">cucumber-jvm-version</span><span style="color: teal;">></span>1.1.5<span style="color: teal;"></</span><span style="color: #3f7f7f;">cucumber-jvm-version</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">features-directory</span><span style="color: teal;">></span>src/test/features<span style="color: teal;"></</span><span style="color: #3f7f7f;">features-directory</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">gems-directory</span><span style="color: teal;">></span>${project.build.directory}/gems<span style="color: teal;"></</span><span style="color: #3f7f7f;">gems-directory</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">properties</span><span style="color: teal;">></span><br />
<br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">dependencies</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">dependency</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">groupId</span><span style="color: teal;">></span>org.jruby<span style="color: teal;"></</span><span style="color: #3f7f7f;">groupId</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">artifactId</span><span style="color: teal;">></span>jruby-complete<span style="color: teal;"></</span><span style="color: #3f7f7f;">artifactId</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">version</span><span style="color: teal;">></span>1.7.4<span style="color: teal;"></</span><span style="color: #3f7f7f;">version</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">scope</span><span style="color: teal;">></span>test<span style="color: teal;"></</span><span style="color: #3f7f7f;">scope</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">dependency</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">dependency</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">groupId</span><span style="color: teal;">></span>info.cukes<span style="color: teal;"></</span><span style="color: #3f7f7f;">groupId</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">artifactId</span><span style="color: teal;">></span>cucumber-jruby<span style="color: teal;"></</span><span style="color: #3f7f7f;">artifactId</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">version</span><span style="color: teal;">></span>${cucumber-jvm-version}<span style="color: teal;"></</span><span style="color: #3f7f7f;">version</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">scope</span><span style="color: teal;">></span>test<span style="color: teal;"></</span><span style="color: #3f7f7f;">scope</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">dependency</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">dependencies</span><span style="color: teal;">></span><br />
<br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">build</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">testResources</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">testResource</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">directory</span><span style="color: teal;">></span>${basedir}/${features-directory}<span style="color: teal;"></</span><span style="color: #3f7f7f;">directory</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">filtering</span><span style="color: teal;">></span>true<span style="color: teal;"></</span><span style="color: #3f7f7f;">filtering</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">testResource</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">testResources</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">plugins</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">plugin</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">groupId</span><span style="color: teal;">></span>org.apache.maven.plugins<span style="color: teal;"></</span><span style="color: #3f7f7f;">groupId</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">artifactId</span><span style="color: teal;">></span>maven-antrun-plugin<span style="color: teal;"></</span><span style="color: #3f7f7f;">artifactId</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">version</span><span style="color: teal;">></span>1.7<span style="color: teal;"></</span><span style="color: #3f7f7f;">version</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">executions</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">execution</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">phase</span><span style="color: teal;">></span>generate-test-resources<span style="color: teal;"></</span><span style="color: #3f7f7f;">phase</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">configuration</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">target</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">sequential</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">echo</span> <span style="color: #7f007f;">message</span>=<span style="color: #2a00ff; font-style: italic;">"Installing bundler gem"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">java</span> <span style="color: #7f007f;">jar</span>=<span style="color: #2a00ff; font-style: italic;">"${maven.dependency.org.jruby.jruby-complete.jar.path}"</span><br />
<span style="color: #7f007f;">fork</span>=<span style="color: #2a00ff; font-style: italic;">"true"</span> <span style="color: #7f007f;">failonerror</span>=<span style="color: #2a00ff; font-style: italic;">"true"</span> <span style="color: #7f007f;">maxmemory</span>=<span style="color: #2a00ff; font-style: italic;">"256m"</span><br />
<span style="color: #7f007f;">newenvironment</span>=<span style="color: #2a00ff; font-style: italic;">"true"</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">arg</span> <span style="color: #7f007f;">value</span>=<span style="color: #2a00ff; font-style: italic;">"-S"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">arg</span> <span style="color: #7f007f;">value</span>=<span style="color: #2a00ff; font-style: italic;">"gem"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">arg</span> <span style="color: #7f007f;">value</span>=<span style="color: #2a00ff; font-style: italic;">"install"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">arg</span> <span style="color: #7f007f;">value</span>=<span style="color: #2a00ff; font-style: italic;">"bundler"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">arg</span> <span style="color: #7f007f;">value</span>=<span style="color: #2a00ff; font-style: italic;">"-i"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">arg</span> <span style="color: #7f007f;">value</span>=<span style="color: #2a00ff; font-style: italic;">"${gems-directory}"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">arg</span> <span style="color: #7f007f;">value</span>=<span style="color: #2a00ff; font-style: italic;">"--no-ri"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">arg</span> <span style="color: #7f007f;">value</span>=<span style="color: #2a00ff; font-style: italic;">"--no-rdoc"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">java</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">echo</span> <span style="color: #7f007f;">message</span>=<span style="color: #2a00ff; font-style: italic;">"Doing bundle install"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">java</span> <span style="color: #7f007f;">jar</span>=<span style="color: #2a00ff; font-style: italic;">"${maven.dependency.org.jruby.jruby-complete.jar.path}"</span><br />
<span style="color: #7f007f;">fork</span>=<span style="color: #2a00ff; font-style: italic;">"true"</span> <span style="color: #7f007f;">failonerror</span>=<span style="color: #2a00ff; font-style: italic;">"true"</span> <span style="color: #7f007f;">maxmemory</span>=<span style="color: #2a00ff; font-style: italic;">"512m"</span><br />
<span style="color: #7f007f;">newenvironment</span>=<span style="color: #2a00ff; font-style: italic;">"true"</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">env</span> <span style="color: #7f007f;">key</span>=<span style="color: #2a00ff; font-style: italic;">"GEM_HOME"</span> <span style="color: #7f007f;">path</span>=<span style="color: #2a00ff; font-style: italic;">"${gems-directory}"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">arg</span> <span style="color: #7f007f;">value</span>=<span style="color: #2a00ff; font-style: italic;">"-S"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">arg</span> <span style="color: #7f007f;">value</span>=<span style="color: #2a00ff; font-style: italic;">"${gems-directory}/bin/bundle"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">arg</span> <span style="color: #7f007f;">value</span>=<span style="color: #2a00ff; font-style: italic;">"install"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">arg</span> <span style="color: #7f007f;">value</span>=<span style="color: #2a00ff; font-style: italic;">"--gemfile=${basedir}/Gemfile"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">java</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">sequential</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">target</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">configuration</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">goals</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">goal</span><span style="color: teal;">></span>run<span style="color: teal;"></</span><span style="color: #3f7f7f;">goal</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">goals</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">execution</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">execution</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">phase</span><span style="color: teal;">></span>test<span style="color: teal;"></</span><span style="color: #3f7f7f;">phase</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">id</span><span style="color: teal;">></span>run-cucumbers<span style="color: teal;"></</span><span style="color: #3f7f7f;">id</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">goals</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">goal</span><span style="color: teal;">></span>run<span style="color: teal;"></</span><span style="color: #3f7f7f;">goal</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">goals</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">configuration</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">target</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">echo</span> <span style="color: #7f007f;">message</span>=<span style="color: #2a00ff; font-style: italic;">"Running Cucumber Ruby Features"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">java</span> <span style="color: #7f007f;">fork</span>=<span style="color: #2a00ff; font-style: italic;">"true"</span> <span style="color: #7f007f;">classname</span>=<span style="color: #2a00ff; font-style: italic;">"cucumber.api.cli.Main"</span><br />
<span style="color: #7f007f;">classpathref</span>=<span style="color: #2a00ff; font-style: italic;">"maven.test.classpath"</span> <span style="color: #7f007f;">failonerror</span>=<span style="color: #2a00ff; font-style: italic;">"true"</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">env</span> <span style="color: #7f007f;">key</span>=<span style="color: #2a00ff; font-style: italic;">"GEM_HOME"</span> <span style="color: #7f007f;">path</span>=<span style="color: #2a00ff; font-style: italic;">"${gems-directory}"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">env</span> <span style="color: #7f007f;">key</span>=<span style="color: #2a00ff; font-style: italic;">"RUBY_VERSION"</span> <span style="color: #7f007f;">value</span>=<span style="color: #2a00ff; font-style: italic;">"2.0"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">arg</span> <span style="color: #7f007f;">value</span>=<span style="color: #2a00ff; font-style: italic;">"-f"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">arg</span> <span style="color: #7f007f;">value</span>=<span style="color: #2a00ff; font-style: italic;">"pretty"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">arg</span> <span style="color: #7f007f;">value</span>=<span style="color: #2a00ff; font-style: italic;">"--glue"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">arg</span> <span style="color: #7f007f;">value</span>=<span style="color: #2a00ff; font-style: italic;">"${features-directory}"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">arg</span> <span style="color: #7f007f;">value</span>=<span style="color: #2a00ff; font-style: italic;">"${features-directory}"</span> <span style="color: teal;">/></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">java</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">target</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">configuration</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">execution</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">executions</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">plugin</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">plugins</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">build</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">project</span><span style="color: teal;">></span><br />
</div>
</div>
<br />
<h4>
<a href="" id="using_maven_plugins">Using the JRuby and Cucumber-JVM Plug-ins</a></h4>
This pom forks new processes for installing bundler, installing the bundles required by the tests and running the tests themselves. The <a href="https://github.com/timezra/jruby-maven-plugin">jruby-maven-plugin</a> and <a href="https://github.com/timezra/cucumber-jvm-maven-plugin">cucumber-jvm-maven-plugin</a> can be configured to run specifications without relying on the <a href="http://maven.apache.org/plugins/maven-antrun-plugin">maven-antrun-plugin</a> to execute new processes. Configuration is similar to the command-line JRuby and Cucumber-JVM clients, and in fact, each plug-in can take a raw CLI configuration if the built-in goals are not sufficient.<br />
Given the same project layout as above, this pom will perform the identical steps in the same Maven process.<br />
<em>pom.xml</em>
<div style="background-color: white; border-style: dashed; border-width: thin; height: 350px; overflow: auto; padding: 1em;">
<div style="font-family: courier new; font-size: 10pt;">
<span style="color: teal;"><</span><span style="color: #3f7f7f;">project</span> <span style="color: #7f007f;">xmlns</span>=<span style="color: #2a00ff; font-style: italic;">"http://maven.apache.org/POM/4.0.0"</span> <span style="color: #7f007f;">xmlns:xsi</span>=<span style="color: #2a00ff; font-style: italic;">"http://www.w3.org/2001/XMLSchema-instance"</span><br />
<span style="color: #7f007f;">xsi:schemaLocation</span>=<span style="color: #2a00ff; font-style: italic;">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">modelVersion</span><span style="color: teal;">></span>4.0.0<span style="color: teal;"></</span><span style="color: #3f7f7f;">modelVersion</span><span style="color: teal;">></span><br />
<br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">groupId</span><span style="color: teal;">></span>timezra.maven<span style="color: teal;"></</span><span style="color: #3f7f7f;">groupId</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">artifactId</span><span style="color: teal;">></span>cucumber-jvm-from-maven<span style="color: teal;"></</span><span style="color: #3f7f7f;">artifactId</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">version</span><span style="color: teal;">></span>1.0.0-SNAPSHOT<span style="color: teal;"></</span><span style="color: #3f7f7f;">version</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">name</span><span style="color: teal;">></span>cucumber-jvm-from-maven<span style="color: teal;"></</span><span style="color: #3f7f7f;">name</span><span style="color: teal;">></span><br />
<br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">properties</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">project.build.sourceEncoding</span><span style="color: teal;">></span>UTF-8<span style="color: teal;"></</span><span style="color: #3f7f7f;">project.build.sourceEncoding</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">gems-directory</span><span style="color: teal;">></span>${project.build.directory}/gems<span style="color: teal;"></</span><span style="color: #3f7f7f;">gems-directory</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">jruby-version</span><span style="color: teal;">></span>1.7.4<span style="color: teal;"></</span><span style="color: #3f7f7f;">jruby-version</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">cucumber-jvm-version</span><span style="color: teal;">></span>1.1.5<span style="color: teal;"></</span><span style="color: #3f7f7f;">cucumber-jvm-version</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">properties</span><span style="color: teal;">></span><br />
<br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">profiles</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">profile</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">id</span><span style="color: teal;">></span>default-profile<span style="color: teal;"></</span><span style="color: #3f7f7f;">id</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">activation</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">activeByDefault</span><span style="color: teal;">></span>true<span style="color: teal;"></</span><span style="color: #3f7f7f;">activeByDefault</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">activation</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">properties</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">runCucumbers</span><span style="color: teal;">></span>true<span style="color: teal;"></</span><span style="color: #3f7f7f;">runCucumbers</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">properties</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">profile</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">profile</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">id</span><span style="color: teal;">></span>skip-tests<span style="color: teal;"></</span><span style="color: #3f7f7f;">id</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">activation</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">activeByDefault</span><span style="color: teal;">></span>false<span style="color: teal;"></</span><span style="color: #3f7f7f;">activeByDefault</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">property</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">name</span><span style="color: teal;">></span>skipTests<span style="color: teal;"></</span><span style="color: #3f7f7f;">name</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">value</span><span style="color: teal;">></span>true<span style="color: teal;"></</span><span style="color: #3f7f7f;">value</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">property</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">activation</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">properties</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">runCucumbers</span><span style="color: teal;">></span>false<span style="color: teal;"></</span><span style="color: #3f7f7f;">runCucumbers</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">properties</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">profile</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">profile</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">id</span><span style="color: teal;">></span>run-tests<span style="color: teal;"></</span><span style="color: #3f7f7f;">id</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">activation</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">activeByDefault</span><span style="color: teal;">></span>true<span style="color: teal;"></</span><span style="color: #3f7f7f;">activeByDefault</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">property</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">name</span><span style="color: teal;">></span>runCucumbers<span style="color: teal;"></</span><span style="color: #3f7f7f;">name</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">value</span><span style="color: teal;">></span>true<span style="color: teal;"></</span><span style="color: #3f7f7f;">value</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">property</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">activation</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">build</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">testResources</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">testResource</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">directory</span><span style="color: teal;">></span>src/test/features<span style="color: teal;"></</span><span style="color: #3f7f7f;">directory</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">filtering</span><span style="color: teal;">></span>true<span style="color: teal;"></</span><span style="color: #3f7f7f;">filtering</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">testResource</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">testResources</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">plugins</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">plugin</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">groupId</span><span style="color: teal;">></span>timezra.maven<span style="color: teal;"></</span><span style="color: #3f7f7f;">groupId</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">artifactId</span><span style="color: teal;">></span>jruby-maven-plugin<span style="color: teal;"></</span><span style="color: #3f7f7f;">artifactId</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">version</span><span style="color: teal;">></span>${jruby-version}<span style="color: teal;"></</span><span style="color: #3f7f7f;">version</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">executions</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">execution</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">id</span><span style="color: teal;">></span>install-bundles<span style="color: teal;"></</span><span style="color: #3f7f7f;">id</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">phase</span><span style="color: teal;">></span>pre-integration-test<span style="color: teal;"></</span><span style="color: #3f7f7f;">phase</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">goals</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">goal</span><span style="color: teal;">></span>gem-install<span style="color: teal;"></</span><span style="color: #3f7f7f;">goal</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">goal</span><span style="color: teal;">></span>bundle-install<span style="color: teal;"></</span><span style="color: #3f7f7f;">goal</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">goals</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">configuration</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">gem_home</span><span style="color: teal;">></span>${gems-directory}<span style="color: teal;"></</span><span style="color: #3f7f7f;">gem_home</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">gem</span><span style="color: teal;">></span>bundler<span style="color: teal;"></</span><span style="color: #3f7f7f;">gem</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">gemfile</span><span style="color: teal;">></span>${project.basedir}/Gemfile<span style="color: teal;"></</span><span style="color: #3f7f7f;">gemfile</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">configuration</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">execution</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">executions</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">plugin</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">plugin</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">groupId</span><span style="color: teal;">></span>timezra.maven<span style="color: teal;"></</span><span style="color: #3f7f7f;">groupId</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">artifactId</span><span style="color: teal;">></span>cucumber-jvm-maven-plugin<span style="color: teal;"></</span><span style="color: #3f7f7f;">artifactId</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">version</span><span style="color: teal;">></span>${cucumber-jvm-version}<span style="color: teal;"></</span><span style="color: #3f7f7f;">version</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: teal;"><</span><span style="color: #3f7f7f;">dependencies</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">dependency</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">groupId</span><span style="color: teal;">></span>org.jruby<span style="color: teal;"></</span><span style="color: #3f7f7f;">groupId</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">artifactId</span><span style="color: teal;">></span>jruby-complete<span style="color: teal;"></</span><span style="color: #3f7f7f;">artifactId</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">version</span><span style="color: teal;">></span>${jruby-version}<span style="color: teal;"></</span><span style="color: #3f7f7f;">version</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">dependency</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">dependencies</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">executions</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">execution</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">id</span><span style="color: teal;">></span>run-cucumbers<span style="color: teal;"></</span><span style="color: #3f7f7f;">id</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">phase</span><span style="color: teal;">></span>integration-test<span style="color: teal;"></</span><span style="color: #3f7f7f;">phase</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">goals</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">goal</span><span style="color: teal;">></span>jruby<span style="color: teal;"></</span><span style="color: #3f7f7f;">goal</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">goals</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">configuration</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">gem_home</span><span style="color: teal;">></span>${gems-directory}<span style="color: teal;"></</span><span style="color: #3f7f7f;">gem_home</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">feature</span><span style="color: teal;">></span>${project.build.testOutputDirectory}<span style="color: teal;"></</span><span style="color: #3f7f7f;">feature</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">configuration</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">execution</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">executions</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">plugin</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">plugins</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">build</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">profile</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">profiles</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">pluginRepositories</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">pluginRepository</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">id</span><span style="color: teal;">></span>tims-repo<span style="color: teal;"></</span><span style="color: #3f7f7f;">id</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">url</span><span style="color: teal;">></span>http://timezra.github.com/maven/releases<span style="color: teal;"></</span><span style="color: #3f7f7f;">url</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">releases</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">enabled</span><span style="color: teal;">></span>true<span style="color: teal;"></</span><span style="color: #3f7f7f;">enabled</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">releases</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">snapshots</span><span style="color: teal;">></span><br />
<span style="color: teal;"><</span><span style="color: #3f7f7f;">enabled</span><span style="color: teal;">></span>false<span style="color: teal;"></</span><span style="color: #3f7f7f;">enabled</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">snapshots</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">pluginRepository</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">pluginRepositories</span><span style="color: teal;">></span><br />
<span style="color: teal;"></</span><span style="color: #3f7f7f;">project</span><span style="color: teal;">></span><br />
</div>
</div>
<strong>NB:</strong> If you have set the $GEM_PATH, $GEM_HOME or $RUBY_VERSION environment variables or if you are using RVM (which sets these for you), you will need to unset them before running your specs. When forking a new Java process to run JRuby or Cucumber-JVM, it is possible to configure these new environment variables in the pom, but when running these goals in-process in Maven, these variables must be unset before the run.
<br />
<h4>
<a href="" id="using_maven_archetype">Using the Cucumber-JVM Archetype</a></h4>
There is <a href="https://github.com/timezra/cucumber-jvm-archetype">a Maven archetype</a> for this type of acceptance testing project that will help you get started. With a single command, the boilerplate project layout and pom configuration will be generated automatically so that you can start writing specifications and step definitions right away.<br />
<div style="background-color: black; border-style: dashed; border-width: thin; color: white; overflow: auto; padding: 1em;">
<span style="font-family: courier new; font-size: 10pt;"><br />
$ mvn archetype:generate -DarchetypeCatalog=http://timezra.github.com/maven/releases/archetypes -Dfilter=timezra.maven:cucumber-jvm-archetype<br />
<em>fill in the groupId, artifactId, version and feature information</em><br />
<em>cd to the new project</em><br />
$ unset GEM_PATH GEM_HOME RUBY_VERSION<br />
$ mvn verify<br />
</span><br />
</div>
<br />
<h4>
Conclusion</h4>
This post describes the layout and configuration of a Cucumber-JVM project using both forked java processes and in-process Maven plug-ins to run acceptance tests. A Maven archetype can generate all the boilerplate project configuration, so with a few simple commands you can begin to write Gherkin specifications and run them as part of your continuous build process.
<br />
</body>
</html>
Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com0tag:blogger.com,1999:blog-106449775438946661.post-50673258167206743092012-08-03T12:37:00.000-07:002012-08-04T09:16:30.389-07:00Rapid Innovation and Customer Focus at TaitAfter publication of <a href="http://www.forbes.com/sites/stevedenning/2012/08/02/can-established-manufacturers-transition-to-agile/">an article in Forbes</a> about the shift in global manufacturing from multi-year product cycles to rapid and continuous innovation with a focus on the practices used by <a href="http://wikispeed.com/">WIKISPEED</a> and the coaching provided by <a href="http://www.solutionsiq.com/">SolutionsIQ</a> at industry-leading companies such as <a href="http://www.taitradio.com/">Tait Communications</a>, <a href="http://www.blogger.com/profile/02111513005976951695">Emre Aras</a> posted the following questions on the <a href="http://wikispeed.com/">WIKISPEED</a> mailing list:
<br />
<ul>
<li>What kind of hardware engineering team is it?</li>
<li>What do you do?</li>
<li>Is it like Research and Development Center?</li>
</ul>
Below are my responses.
<br />
<br />
Engagement with the team at <a href="http://www.taitradio.com/">Tait</a> has been particularly interesting because the team comprises mechanical and systems engineers in addition to software engineers and testers, all co-located in a single area with workbenches that contain only the tools and test fixtures necessary to execute on the singular vision for their pilot project. As far as the specific details of what the team was working towards, I am hesitant to give more details than just to say that they were building out a <a href="http://en.wikipedia.org/wiki/Base_station">base station</a> for use by the types of hand-held radios you might see <a href="http://www.taitradio.com/news-and-media/news/2011-news/2011/tait-helps-students-scrutinize-firefighter-communications">firefighters</a>, <a href="http://www.taitradio.com/news-and-media/news/2011-news/2011/sao-paulo-civil-police-upgrades-to-tait-p25-trunked-network">police officers</a> and other <a href="http://www.taitradio.com/news-and-media/news/jim-wells-county,-texas,-chooses-tait-p25-solution">emergency responders</a> using (which is not giving away much since that is what <a href="http://www.taitradio.com/">Tait</a> does). Since all team members were sitting together and working towards the same concise and focused vision, since everyone was aware of what everyone else was doing because of the information radiators used throughout the room and morning just-in-time planning sessions, and since the product owner was always available to answer questions and refocus priorities, the team was able to identify several knowledge gaps that related not just to this individual project but to other projects ongoing at <a href="http://www.taitradio.com/">Tait</a>, the team was able to cut scope responsibly because of new information exposed by members that emerged from the serendipitous conversations that happen when teams work in close and open proximity, the team was able to inspect and adapt daily from the actions that surfaced in afternoon retrospectives, and the team was able to demonstrate a working product to a customer proxy within the span of just 5 days!
<br />
<br />
My role is just to be a catalyst for change. Team members often know what they need to do to get work done. Someone in my role just helps to get team members together in the same space, talking to one another, and using project management frameworks and tools that encourage teams to produce small customer-visible features on a regular cadence.
<br />
<br />
One goal of this project was to deliver a small, fully-realized feature into the hands of a customer and to get immediate feedback on a short timescale, so the project was more than just a theoretical exercise. Another goal of the project was to identify knowledge-gaps in order to minimize risk for ongoing development.Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com2tag:blogger.com,1999:blog-106449775438946661.post-42193928473563035202012-01-16T22:58:00.000-08:002012-01-16T22:58:35.682-08:00BDD With Spock and Selenium<!DOCTYPE html><br />
<html><br />
<head><br />
<link href='http://fonts.googleapis.com/css?family=Indie+Flower' rel='stylesheet' type='text/css'> <br />
<meta charset="UTF-8"><br />
<title>BDD With Spock and Selenium</title><br />
</head><br />
<body><br />
<h4>Goal</h4> <p> To develop a web site specification-first using Spock and Selenium WebDriver.<br />
</p><br />
<h4>tl;dr</h4> <p> The sample code for this project is <a href="https://github.com/timezra/course_registry">available on github</a> and will be a helpful resource for following this article. The interesting technologies showcased include <a href="http://code.google.com/p/spock/">Spock</a>, <a href="http://seleniumhq.org/projects/webdriver/">Selenium WebDriver</a>, <a href="http://code.google.com/p/selenium/wiki/PageObjects">Selenium PageObjects</a>, <a href="http://saucelabs.com/ondemand">Sauce OnDemand</a>, <a href="http://gradle.org/">Gradle</a> and <a href="http://grails.org/">Grails 2.0</a>.<br />
</p><br />
<h4>The Project</h4> <p> Suppose our product owner would like to publish a website for teachers to schedule their classes and for students to register for those courses. At the first backlog grooming, the product owner has prioritized the stories that would constitute a <a href="http://en.wikipedia.org/wiki/Minimum_viable_product">minimum viable product</a>. <br />
</p><br />
<h4><a id="user_stories">User Stories</a></h4> <p> During the team's first sprint planning meeting, we sized the stories, accepted four into the sprint, and have added tasks for each. Our story board for the first sprint contains <a href="http://net.tutsplus.com/articles/news/create-a-sticky-note-effect-in-5-easy-steps-with-css3-and-html5/">sticky notes</a> for our user stories, the acceptance criteria and the individual tasks for each story.<br />
</p><br />
<div style="
overflow-x: auto;
overflow-y: hidden;
padding: 1em;
background-color: white;
border-style: groove;
border-width: medium;"> <div style="
float: left;
text-decoration: none;
color: #000;
font-family: 'Indie Flower', cursive;
width: 96em;"> <!-- User Story 1 --><br />
<div style="
float: left;
padding: 1em;"> <div
style="
-webkit-backface-visibility: hidden;
box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-ms-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-webkit-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-moz-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-o-transform: rotate(-3deg);
-ms-transform: rotate(-3deg);
-webkit-transform: rotate(-3deg);
-moz-transform: rotate(-3deg);
-o-transition: -o-transform .15s linear;
-ms-transition: -ms-transform .15s linear;
-webkit-transition: -webkit-transform .15s linear;
-moz-transition: -moz-transform .15s linear;
position: relative;
z-index: 0;
background: #ffc;
height: 10em;
width: 10em;
padding: 1em;"
onmouseover="
this.style.boxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.msBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.WebkitBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.MozBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.OTransform='scale(1.25)';
this.style.MsTransform='scale(1.25)';
this.style.WebkitTransform='scale(1.25)';
this.style.MozTransform='scale(1.25)';
this.style.zIndex='1';"
onmouseout="
this.style.boxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.msBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.WebkitBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.MozBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.OTransform='rotate(-3deg)';
this.style.MsTransform='rotate(-3deg)';
this.style.WebkitTransform='rotate(-3deg)';
this.style.MozTransform='rotate(-3deg)';
this.style.zIndex='0';"> <p> As a teacher <br />
I want to sign up <br />
So I can add courses <br />
</p> </div> <br />
<div
style="
-webkit-backface-visibility: hidden;
box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-ms-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-webkit-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-moz-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-o-transform: rotate(1deg);
-ms-transform: rotate(1deg);
-webkit-transform: rotate(1deg);
-moz-transform: rotate(1deg);
-o-transition: -o-transform .15s linear;
-ms-transition: -ms-transform .15s linear;
-webkit-transition: -webkit-transform .15s linear;
-moz-transition: -moz-transform .15s linear;
position: relative;
z-index: 0;
background: #ccf;
height: 10em;
width: 20em;
padding: 1em;"
onmouseover="
this.style.boxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.msBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.WebkitBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.MozBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.OTransform='scale(1.25)';
this.style.MsTransform='scale(1.25)';
this.style.WebkitTransform='scale(1.25)';
this.style.MozTransform='scale(1.25)';
this.style.zIndex='1';"
onmouseout="
this.style.boxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.msBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.WebkitBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.MozBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.OTransform='rotate(1deg)';
this.style.MsTransform='rotate(1deg)';
this.style.WebkitTransform='rotate(1deg)';
this.style.MozTransform='rotate(1deg)';
this.style.zIndex='0';"> Acceptance Criteria:<br />
<ul> <li>User is greeted with intro screen</li>
<li>User is able to register as a teacher or to login</li>
<li>After registration or login, a teacher sees account info</li>
</ul> </div> </div><!-- User Story 2 --><div style="
float: left;
padding: 1em;"> <div
style="
-webkit-backface-visibility: hidden;
box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-ms-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-webkit-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-moz-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-o-transform: rotate(4deg);
-ms-transform: rotate(4deg);
-webkit-transform: rotate(4deg);
-moz-transform: rotate(4deg);
-o-transition: -o-transform .15s linear;
-ms-transition: -ms-transform .15s linear;
-webkit-transition: -webkit-transform .15s linear;
-moz-transition: -moz-transform .15s linear;
position: relative;
z-index: 0;
background: #ffc;
height: 10em;
width: 10em;
padding: 1em;"
onmouseover="
this.style.boxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.msBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.WebkitBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.MozBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.OTransform='scale(1.25)';
this.style.MsTransform='scale(1.25)';
this.style.WebkitTransform='scale(1.25)';
this.style.MozTransform='scale(1.25)';
this.style.zIndex='1';"
onmouseout="
this.style.boxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.msBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.WebkitBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.MozBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.OTransform='rotate(4deg)';
this.style.MsTransform='rotate(4deg)';
this.style.WebkitTransform='rotate(4deg)';
this.style.MozTransform='rotate(4deg)';
this.style.zIndex='0';"> <p> As a student <br />
I want to sign up <br />
So I can take courses <br />
</p> </div> <br />
<div
style="
-webkit-backface-visibility: hidden;
box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-ms-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-webkit-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-moz-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-o-transform: rotate(-2deg);
-ms-transform: rotate(-2deg);
-webkit-transform: rotate(-2deg);
-moz-transform: rotate(-2deg);
-o-transition: -o-transform .15s linear;
-ms-transition: -ms-transform .15s linear;
-webkit-transition: -webkit-transform .15s linear;
-moz-transition: -moz-transform .15s linear;
position: relative;
z-index: 0;
background: #ccf;
height: 10em;
width: 20em;
padding: 1em;"
onmouseover="
this.style.boxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.msBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.WebkitBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.MozBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.OTransform='scale(1.25)';
this.style.MsTransform='scale(1.25)';
this.style.WebkitTransform='scale(1.25)';
this.style.MozTransform='scale(1.25)';
this.style.zIndex='1';"
onmouseout="
this.style.boxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.msBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.WebkitBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.MozBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.OTransform='rotate(-2deg)';
this.style.MsTransform='rotate(-2deg)';
this.style.WebkitTransform='rotate(-2deg)';
this.style.MozTransform='rotate(-2deg)';
this.style.zIndex='0';"> Acceptance Criteria:<br />
<ul> <li>User is able to register or to login as a student</li>
<li>After registration or login, a student sees account info</li>
</ul> </div> </div><!-- User Story 3 --><div style="
float: left;
padding: 1em;"> <div
style="
-webkit-backface-visibility: hidden;
box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-ms-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-webkit-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-moz-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-o-transform: rotate(-2deg);
-ms-transform: rotate(-2deg);
-webkit-transform: rotate(-2deg);
-moz-transform: rotate(-2deg);
-o-transition: -o-transform .15s linear;
-ms-transition: -ms-transform .15s linear;
-webkit-transition: -webkit-transform .15s linear;
-moz-transition: -moz-transform .15s linear;
position: relative;
z-index: 0;
background: #ffc;
height: 10em;
width: 10em;
padding: 1em;"
onmouseover="
this.style.boxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.msBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.WebkitBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.MozBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.OTransform='scale(1.25)';
this.style.MsTransform='scale(1.25)';
this.style.WebkitTransform='scale(1.25)';
this.style.MozTransform='scale(1.25)';
this.style.zIndex='1';"
onmouseout="
this.style.boxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.msBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.WebkitBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.MozBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.OTransform='rotate(-2deg)';
this.style.MsTransform='rotate(-2deg)';
this.style.WebkitTransform='rotate(-2deg)';
this.style.MozTransform='rotate(-2deg)';
this.style.zIndex='0';"> <p> As a teacher <br />
I want to add courses <br />
So students can register for them <br />
</p> </div> <br />
<div
style="
-webkit-backface-visibility: hidden;
box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-ms-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-webkit-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-moz-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-o-transform: rotate(3deg);
-ms-transform: rotate(3deg);
-webkit-transform: rotate(3deg);
-moz-transform: rotate(3deg);
-o-transition: -o-transform .15s linear;
-ms-transition: -ms-transform .15s linear;
-webkit-transition: -webkit-transform .15s linear;
-moz-transition: -moz-transform .15s linear;
position: relative;
z-index: 0;
background: #ccf;
height: 10em;
width: 20em;
padding: 1em;"
onmouseover="
this.style.boxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.msBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.WebkitBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.MozBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.OTransform='scale(1.25)';
this.style.MsTransform='scale(1.25)';
this.style.WebkitTransform='scale(1.25)';
this.style.MozTransform='scale(1.25)';
this.style.zIndex='1';"
onmouseout="
this.style.boxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.msBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.WebkitBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.MozBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.OTransform='rotate(3deg)';
this.style.MsTransform='rotate(3deg)';
this.style.WebkitTransform='rotate(3deg)';
this.style.MozTransform='rotate(3deg)';
this.style.zIndex='0';"> Acceptance Criteria:<br />
<ul> <li>A teacher can add a course</li>
<li>Courses occur in a semester</li>
<li>Courses occur in timeslots</li>
<li>Courses can have prerequisites</li>
</ul> </div> </div><!-- User Story 4 --><div style="
float: left;
padding: 1em;"> <div
style="
-webkit-backface-visibility: hidden;
box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-ms-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-webkit-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-moz-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-o-transform: rotate(4deg);
-ms-transform: rotate(4deg);
-webkit-transform: rotate(4deg);
-moz-transform: rotate(4deg);
-o-transition: -o-transform .15s linear;
-ms-transition: -ms-transform .15s linear;
-webkit-transition: -webkit-transform .15s linear;
-moz-transition: -moz-transform .15s linear;
position: relative;
z-index: 0;
background: #ffc;
height: 10em;
width: 10em;
padding: 1em;"
onmouseover="
this.style.boxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.msBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.WebkitBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.MozBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.OTransform='scale(1.25)';
this.style.MsTransform='scale(1.25)';
this.style.WebkitTransform='scale(1.25)';
this.style.MozTransform='scale(1.25)';
this.style.zIndex='1';"
onmouseout="
this.style.boxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.msBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.WebkitBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.MozBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.OTransform='rotate(4deg)';
this.style.MsTransform='rotate(4deg)';
this.style.WebkitTransform='rotate(4deg)';
this.style.MozTransform='rotate(4deg)';
this.style.zIndex='0';"> <p> As a student <br />
I want to register for courses <br />
So I can get credits toward my degree <br />
</p> </div> <br />
<div
style="
-webkit-backface-visibility: hidden;
box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-ms-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-webkit-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-moz-box-shadow: 5px 5px 7px rgba(33, 33, 33, .7);
-o-transform: rotate(-1deg);
-ms-transform: rotate(-1deg);
-webkit-transform: rotate(-1deg);
-moz-transform: rotate(-1deg);
-o-transition: -o-transform .15s linear;
-ms-transition: -ms-transform .15s linear;
-webkit-transition: -webkit-transform .15s linear;
-moz-transition: -moz-transform .15s linear;
position: relative;
z-index: 0;
background: #ccf;
height: 10em;
width: 20em;
padding: 1em;"
onmouseover="
this.style.boxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.msBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.WebkitBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.MozBoxShadow='10px 10px 7px rgba(0,0,0,.7)';
this.style.OTransform='scale(1.25)';
this.style.MsTransform='scale(1.25)';
this.style.WebkitTransform='scale(1.25)';
this.style.MozTransform='scale(1.25)';
this.style.zIndex='1';"
onmouseout="
this.style.boxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.msBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.WebkitBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.MozBoxShadow='5px 5px 7px rgba(33,33,33,.7)';
this.style.OTransform='rotate(-1deg)';
this.style.MsTransform='rotate(-1deg)';
this.style.WebkitTransform='rotate(-1deg)';
this.style.MozTransform='rotate(-1deg)';
this.style.zIndex='0';"> Acceptance Criteria:<br />
<ul> <li>A student can register for a course</li>
<li>A student must take any pre-reqs before registering for a course</li>
<li>A student cannot take 2 courses that occur in the same timeslot</li>
</ul> </div> </div> </div> </div> <div style="clear: both"></div><br />
<h4>Project Structure</h4> <p> We will create a top-level project <em>course_registry</em> and the two sub-projects <em>web</em> and <em>specifications</em>. We will also create a <em>build.gradle</em> file in the root along with <em>settings.gradle</em> and a <em>build.gradle</em> file in the <em>specifications</em> subproject for running automated acceptance tests (While <a href="http://www.gradle.org/userguide/0.5.2/userguidech17.html#x48-13000017.2.1">this is not strictly necessary</a>, it will help to keep our project boundaries clear).<br />
</p> <div style="
overflow: auto;
padding: 1em;
background-color: black;
color: white;
border-style: dashed;
border-width: thin"> <span style="font-family: courier new; font-size: 11pt;"><br />
course_registry<br />
.<br />
|____build.gradle<br />
|____settings.gradle<br />
| specifications<br />
| |____build.gradle<br />
| web<br />
</span><br />
</div> <br />
<em>course_registry/build.gradle</em><br />
<div style="
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin"> <span style="font-family: courier new; font-size: 11pt;"><span style="color: rgb(0,0,0);">allprojects</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">apply</span> <span style="color: rgb(0,0,0);">plugin:</span> <span style="color: rgb(255,0,204);">'eclipse'</span><br />
<span style="color: rgb(0,0,0);">version</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(255,0,204);">'1.0.0-SNAPSHOT'</span><br />
<span style="color: rgb(0,0,0);">group</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(255,0,204);">'timezra.course_registry'</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="color: rgb(0,0,0);">subprojects</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">sourceCompatibility</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(205,50,0);">1</span><span style="color: rgb(0,0,0);">.</span><span style="color: rgb(205,50,0);">6</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
</span><br />
</div> <br />
<em>course_registry/settings.gradle</em><br />
<div style="
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin"> <span style="font-family: courier new; font-size: 11pt;"><span style="color: rgb(0,0,0);">include</span> <span style="color: rgb(255,0,204);">'web'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(255,0,204);">'specifications'</span><br />
</span><br />
</div> <br />
<em>course_registry/specifications/build.gradle</em><br />
<div style="
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin"> <div style="font-family: courier new; width: 80em; font-size: 11pt;"><span style="color: rgb(0,0,0);">apply</span> <span style="color: rgb(0,0,0);">plugin:</span> <span style="color: rgb(255,0,204);">'groovy'</span><br />
<br />
<span style="color: rgb(0,0,0);">repositories</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">mavenCentral()</span><br />
<span style="color: rgb(0,0,0);">mavenRepo</span> <span style="color: rgb(0,0,0);">url:</span> <span style="color: rgb(255,0,204);">"http://m2repo.spockframework.org/snapshots"</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="color: rgb(0,0,0);">dependencies</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">groovy</span> <span style="color: rgb(0,0,0);">group:</span> <span style="color: rgb(255,0,204);">'org.codehaus.groovy'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">name:</span> <span style="color: rgb(255,0,204);">'groovy'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">version:</span> <span style="color: rgb(255,0,204);">'1.8.5'</span><br />
<span style="color: rgb(0,0,0);">testCompile</span> <span style="color: rgb(0,0,0);">group:</span> <span style="color: rgb(255,0,204);">'org.spockframework'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">name:</span> <span style="color: rgb(255,0,204);">'spock-core'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">version:</span> <span style="color: rgb(255,0,204);">'0.6-groovy-1.8-SNAPSHOT'</span><br />
<span style="color: rgb(0,0,0);">testCompile</span> <span style="color: rgb(0,0,0);">group:</span> <span style="color: rgb(255,0,204);">'org.seleniumhq.selenium'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">name:</span> <span style="color: rgb(255,0,204);">'selenium-java'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">version:</span> <span style="color: rgb(255,0,204);">'2.16.1'</span><br />
<span style="color: rgb(0,0,0);">testCompile</span> <span style="color: rgb(0,0,0);">group:</span> <span style="color: rgb(255,0,204);">'junit'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">name:</span> <span style="color: rgb(255,0,204);">'junit'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">version:</span> <span style="color: rgb(255,0,204);">'4.10'</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
</div> </div> <br />
<p> We will create a <em>src/test/groovy</em> folder in the <em>specifications</em> project. At this point we can generate Eclipse .project and .classpath files for all the projects from the project root in order to work within an IDE.<br />
</p> <div style="
overflow: auto;
padding: 1em;
background-color: black;
color: white;
border-style: dashed;
border-width: thin"> <span style="font-family: courier new; font-size: 11pt;"><br />
<span style="color: green;">course_registry $></span> gradle eclipseProject<br />
<span style="color: green;">course_registry $></span> gradle eclipseClasspath<br />
</span><br />
</div><br />
<h4>The Teacher Registration Spec</h4> <p> We are now able to write the first specification for our acceptance criteria.<br />
</p> <br />
<em>timezra/course_registry/TeacherRegistrationSpec.groovy</em><br />
<div style="
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin"> <span style="font-family: courier new; font-size: 11pt;"><span style="font-weight: bold; color: rgb(151,44,120);">package</span> <span style="color: rgb(0,0,0);">timezra.course_registry</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">import</span> <span style="font-weight: bold; color: rgb(151,44,120);">static</span> <span style="color: rgb(0,0,0);">java.util.concurrent.TimeUnit.SECONDS</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">import</span> <span style="color: rgb(0,0,0);">org.openqa.selenium.WebDriver</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">import</span> <span style="color: rgb(0,0,0);">org.openqa.selenium.firefox.FirefoxDriver</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">import</span> <span style="color: rgb(0,0,0);">spock.lang.Specification</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">class</span> <span style="color: rgb(0,0,0);">TeacherRegistrationSpec</span> <span style="font-weight: bold; color: rgb(151,44,120);">extends</span> <span style="color: rgb(0,0,0);">Specification</span> <span style="color: rgb(0,0,0);">{</span><br />
<br />
<span style="color: rgb(0,0,0);">WebDriver</span> <span style="color: rgb(0,0,0);">driver</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">setup()</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">driver</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(151,44,120);">new</span> <span style="color: rgb(0,0,0);">FirefoxDriver()</span><br />
<span style="color: rgb(0,0,0);">driver.manage().timeouts().implicitlyWait</span> <span style="color: rgb(205,50,0);">10</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">SECONDS</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">cleanup()</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">driver.quit()</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(255,0,204);">"a user is greeted with an intro screen"</span><span style="color: rgb(0,0,0);">()</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">when:</span><br />
<span style="color: rgb(0,0,0);">driver.get</span> <span style="color: rgb(255,0,204);">"http://localhost:8080/course_registry"</span><br />
<br />
<span style="color: rgb(0,0,0);">then:</span><br />
<span style="color: rgb(0,0,0);">driver.title</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(255,0,204);">"Course Registry Home"</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
</span><br />
</div><br />
<p> We can run this spec and watch it fail.<br />
</p> <div style="
overflow: auto;
padding: 1em;
background-color: black;
color: white;
border-style: dashed;
border-width: thin"> <div style="font-family: courier new; width: 80em; font-size: 11pt;"> <span style="color: green;">course_registry $></span> gradle test --info<br />
....<br />
Test a user is greeted with an intro screen(timezra.course_registry.TeacherRegistrationSpec) FAILED: org.gradle.messaging.remote.internal.PlaceholderException: org.spockframework.runtime.SpockComparisonFailure: Condition not satisfied:<br />
<br />
driver.title == "Course Registry Home"<br />
| | |<br />
| | false<br />
| | 17 differences (15% similarity)<br />
| | (Pr)o(bl-)e(m) (load)i(ng--) (pag)e<br />
| | (C-)o(urs)e(-) (Reg-)i(stry) (Hom)e<br />
| Problem loading page<br />
org.openqa.selenium.firefox.FirefoxDriver@4532be10<br />
<br />
Test timezra.course_registry.TeacherRegistrationSpec FAILED<br />
Gradle Worker 1 finished executing tests.<br />
1 test completed, 1 failure<br />
<br />
<span style="color: red;">FAILURE: Build failed with an exception.</span><br />
....<br />
</div> </div> <br />
<h4>Satisfying the Spec</h4> <p> Suppose the team decides to use Grails 2.0 to implement the specification. This is not a restriction based on our other technology choices, since gradle is <a href="http://www.gradle.org/userguide/0.5.2/userguidech17.html#x48-12700017.1">a general purpose build tool</a> and since our specification defines how a user will interact with our web project entirely through a browser. The decision is based on the convenience of the framework, community support, the plug-in ecosystem and the skills of the developers.<br />
</p> <p> First, we need to create an empty <em>web/grails-app</em> directory to indicate to the grails bootstrap that the project will be a grails application.<br />
Then, we will configure our web build for Grails 2.0 in a new <em>web/build.gradle</em> file.<br />
</p> <em>web/build.gradle</em><br />
<div style="
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin"> <div style="font-family: courier new; width: 80em; font-size: 11pt;"><span style="color: rgb(0,0,0);">buildscript</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">repositories</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">mavenCentral()</span><br />
<span style="color: rgb(0,0,0);">mavenRepo</span> <span style="color: rgb(0,0,0);">url:</span> <span style="color: rgb(255,0,204);">'https://repository.jboss.org/nexus/content/groups/public/'</span><br />
<span style="color: rgb(0,0,0);">mavenRepo</span> <span style="color: rgb(0,0,0);">url:</span> <span style="color: rgb(255,0,204);">'http://repo.grails.org/grails/repo'</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="color: rgb(0,0,0);">dependencies</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">classpath</span> <span style="color: rgb(0,0,0);">group:</span> <span style="color: rgb(255,0,204);">'org.grails'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">name:</span> <span style="color: rgb(255,0,204);">'grails-gradle-plugin'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">version:</span> <span style="color: rgb(255,0,204);">'1.1.0'</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="color: rgb(0,0,0);">grailsVersion</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(255,0,204);">'2.0.0'</span><br />
<span style="color: rgb(0,0,0);">apply</span> <span style="color: rgb(0,0,0);">plugin:</span> <span style="color: rgb(255,0,204);">'grails'</span><br />
<br />
<span style="color: rgb(0,0,0);">dependencies</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">compile</span> <span style="color: rgb(0,0,0);">group:</span> <span style="color: rgb(255,0,204);">'org.grails'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">name:</span> <span style="color: rgb(255,0,204);">'grails-resources'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">version:</span> <span style="color: rgb(0,0,0);">grailsVersion</span><br />
<span style="color: rgb(0,0,0);">compile</span> <span style="color: rgb(0,0,0);">group:</span> <span style="color: rgb(255,0,204);">'org.grails'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">name:</span> <span style="color: rgb(255,0,204);">'grails-crud'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">version:</span> <span style="color: rgb(0,0,0);">grailsVersion</span><br />
<span style="color: rgb(0,0,0);">compile</span> <span style="color: rgb(0,0,0);">group:</span> <span style="color: rgb(255,0,204);">'org.grails'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">name:</span> <span style="color: rgb(255,0,204);">'grails-hibernate'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">version:</span> <span style="color: rgb(0,0,0);">grailsVersion</span><br />
<span style="color: rgb(0,0,0);">compile</span> <span style="color: rgb(0,0,0);">group:</span> <span style="color: rgb(255,0,204);">'org.grails'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">name:</span> <span style="color: rgb(255,0,204);">'grails-plugin-datasource'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">version:</span> <span style="color: rgb(0,0,0);">grailsVersion</span><br />
<span style="color: rgb(0,0,0);">runtime</span> <span style="color: rgb(0,0,0);">group:</span> <span style="color: rgb(255,0,204);">'org.grails'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">name:</span> <span style="color: rgb(255,0,204);">'grails-plugin-log4j'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">version:</span> <span style="color: rgb(0,0,0);">grailsVersion</span><br />
<span style="color: rgb(0,0,0);">runtime</span> <span style="color: rgb(0,0,0);">group:</span> <span style="color: rgb(255,0,204);">'org.grails'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">name:</span> <span style="color: rgb(255,0,204);">'grails-plugin-url-mappings'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">version:</span> <span style="color: rgb(0,0,0);">grailsVersion</span><br />
<span style="color: rgb(0,0,0);">runtime</span> <span style="color: rgb(0,0,0);">group:</span> <span style="color: rgb(255,0,204);">'org.grails'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">name:</span> <span style="color: rgb(255,0,204);">'grails-plugin-gsp'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">version:</span> <span style="color: rgb(0,0,0);">grailsVersion</span><br />
<span style="color: rgb(0,0,0);">runtime</span> <span style="color: rgb(0,0,0);">group:</span> <span style="color: rgb(255,0,204);">'org.grails'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">name:</span> <span style="color: rgb(255,0,204);">'grails-plugin-filters'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">version:</span> <span style="color: rgb(0,0,0);">grailsVersion</span><br />
<span style="color: rgb(0,0,0);">runtime</span> <span style="color: rgb(0,0,0);">group:</span> <span style="color: rgb(255,0,204);">'org.grails'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">name:</span> <span style="color: rgb(255,0,204);">'grails-plugin-scaffolding'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">version:</span> <span style="color: rgb(0,0,0);">grailsVersion</span><br />
<span style="color: rgb(0,0,0);">runtime</span> <span style="color: rgb(0,0,0);">group:</span> <span style="color: rgb(255,0,204);">'org.grails'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">name:</span> <span style="color: rgb(255,0,204);">'grails-plugin-services'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">version:</span> <span style="color: rgb(0,0,0);">grailsVersion</span><br />
<span style="color: rgb(0,0,0);">runtime</span> <span style="color: rgb(0,0,0);">group:</span> <span style="color: rgb(255,0,204);">'org.grails'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">name:</span> <span style="color: rgb(255,0,204);">'grails-plugin-servlets'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">version:</span> <span style="color: rgb(0,0,0);">grailsVersion</span><br />
<span style="color: rgb(0,0,0);">runtime</span> <span style="color: rgb(0,0,0);">group:</span> <span style="color: rgb(255,0,204);">'com.h2database'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">name:</span> <span style="color: rgb(255,0,204);">'h2'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">version:</span> <span style="color: rgb(255,0,204);">'1.3.163'</span><br />
<span style="color: rgb(0,0,0);">runtime</span> <span style="color: rgb(0,0,0);">group:</span> <span style="color: rgb(255,0,204);">'net.sf.ehcache'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">name:</span> <span style="color: rgb(255,0,204);">'ehcache-core'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">version:</span> <span style="color: rgb(255,0,204);">'2.4.6'</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="color: rgb(0,0,0);">repositories</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">mavenCentral()</span><br />
<span style="color: rgb(0,0,0);">mavenRepo</span> <span style="color: rgb(0,0,0);">url:</span> <span style="color: rgb(255,0,204);">'https://repository.jboss.org/nexus/content/groups/public/'</span><br />
<span style="color: rgb(0,0,0);">mavenRepo</span> <span style="color: rgb(0,0,0);">url:</span> <span style="color: rgb(255,0,204);">'http://repo.grails.org/grails/repo'</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
</div> </div> <br />
<p> From the project root we will initialize the grails project.<br />
</p> <div style="
overflow: auto;
padding: 1em;
background-color: black;
color: white;
border-style: dashed;
border-width: thin"> <div style="font-family: courier new; width: 80em; font-size: 11pt;"> <span style="color: green;">course_registry $></span> gradle grails-init<br />
:web:grails-init<br />
The ResolvedArtifact.getResolvedDependency() method is deprecated and will be removed in the next version of Gradle.<br />
<span style="color:olive;">|</span> Configuring classpath<br />
<span style="color:red;">| Error</span> log4j:WARN No appenders could be found for logger (org.springframework.core.io.support.PathMatchingResourcePatternResolver).<br />
<span style="color:red;">| Error</span> log4j:WARN Please initialize the log4j system properly.<br />
<span style="color:red;">| Error</span> log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.<br />
<span style="color:olive;">|</span> Environment set to development.....<br />
<br />
BUILD SUCCESSFUL<br />
<br />
Total time: 1 mins 36.328 secs<br />
</div> </div> <br />
<p> We can satisfy the spec simply by modifying <em>application.properties</em> with the expected web application deployment path and project version, the homepage to include the expected title, and <em>messages.properties</em> to contain the expected messages.<br />
</p> <br />
<em>web/application.properties</em><br />
<div style="
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin"> <span style="font-family: courier new; font-size: 11pt;"><span style="color: rgb(0,0,0);">app.grails.version</span><span style="color: rgb(0,0,0);">=</span><span style="color: rgb(42,0,255);">2.0.0</span><br />
<span style="color: rgb(0,0,0);">app.name</span><span style="color: rgb(0,0,0);">=</span><span style="color: rgb(42,0,255);">course_registry</span><br />
<span style="color: rgb(0,0,0);">app.servlet.version</span><span style="color: rgb(0,0,0);">=</span><span style="color: rgb(42,0,255);">2.5</span><br />
<span style="color: rgb(0,0,0);">app.version</span><span style="color: rgb(0,0,0);">=</span><span style="color: rgb(42,0,255);">1.0.0-SNAPSHOT</span></span><br />
</div> <br />
<em>web/grails-app/views/index.gsp</em><br />
<div style="
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin"> <span style="font-family: courier new; font-size: 11pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">html</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">head</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">title</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">g:message</span> <span style="color: rgb(127,0,127);">code</span>=<span style="font-style: italic; color: rgb(42,0,255);">"home.title"</span> <span style="color: rgb(0,128,128);">/></span><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">title</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">meta</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"layout"</span> <span style="color: rgb(127,0,127);">content</span>=<span style="font-style: italic; color: rgb(42,0,255);">"main"</span> <span style="color: rgb(0,128,128);">/></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">style</span> <span style="color: rgb(127,0,127);">type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"text/css"</span> <span style="color: rgb(127,0,127);">media</span>=<span style="font-style: italic; color: rgb(42,0,255);">"screen"</span><span style="color: rgb(0,128,128);">></span><br />
<span style="font-style: italic; color: rgb(63,127,127);">#pageBody</span> {<br />
<span style="color: rgb(127,0,127);">margin-left</span>: <span style="font-style: italic; color: rgb(42,0,225);">280px</span>;<br />
<span style="color: rgb(127,0,127);">margin-right</span>: <span style="font-style: italic; color: rgb(42,0,225);">20px</span>;<br />
}<br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">style</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">head</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">body</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">div</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"pageBody"</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"dialog"</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">p</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">g:message</span> <span style="color: rgb(127,0,127);">code</span>=<span style="font-style: italic; color: rgb(42,0,255);">"home.welcome.message"</span> <span style="color: rgb(0,128,128);">/></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">p</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">div</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">body</span><span style="color: rgb(0,128,128);">></span><br />
<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">html</span><span style="color: rgb(0,128,128);">></span></span><br />
</div> <br />
<em>web/grails-app/i18n/messages.properties</em><br />
<div style="
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin"> <span style="font-family: courier new; font-size: 11pt;">....<br />
<span style="color: rgb(0,0,0);">home.title</span><span style="color: rgb(0,0,0);">=</span><span style="color: rgb(42,0,255);">Course</span> <span style="color: rgb(42,0,255);">Registry</span> <span style="color: rgb(42,0,255);">Home</span><br />
<span style="color: rgb(0,0,0);">home.welcome.message</span><span style="color: rgb(0,0,0);">=</span><span style="color: rgb(42,0,255);">Welcome</span> <span style="color: rgb(42,0,255);">to</span> <span style="color: rgb(42,0,255);">the</span> <span style="color: rgb(42,0,255);">course</span> <span style="color: rgb(42,0,255);">registry.</span></span><br />
</div> <br />
<p> We can now add hooks to the specifications project to stop and start the web application before and after running the specifications, respectively.<br />
</p> <em>specifications/build.gradle</em><br />
<div style="
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin"> <span style="font-family: courier new; font-size: 11pt;"><span style="color: rgb(0,0,0);">....</span><br />
<span style="color: rgb(0,0,0);">test.dependsOn</span> <span style="color: rgb(255,0,204);">':web:webStart'</span><br />
<br />
<span style="color: rgb(0,0,0);">gradle.taskGraph.afterTask</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(0,0,0);">Task</span> <span style="color: rgb(0,0,0);">task,</span> <span style="color: rgb(0,0,0);">TaskState</span> <span style="color: rgb(0,0,0);">state</span> <span style="color: rgb(0,0,0);">-></span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">if</span><span style="color: rgb(0,0,0);">(</span><span style="color: rgb(255,0,204);">':specifications:test'</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">task.path)</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">project(</span><span style="color: rgb(255,0,204);">':web'</span><span style="color: rgb(0,0,0);">).tasks.getByPath(</span><span style="color: rgb(255,0,204);">'webStop'</span><span style="color: rgb(0,0,0);">).execute()</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
</span><br />
</div> <br />
<p> These hooks depend on a specific interface in the <em>web</em> project, i.e., the existence of the tasks <em>webStart</em> and <em>webStop</em>. We can deploy the Grails 2.0 artifact to an <a href="http://gradle.org/docs/current/userguide/jetty_plugin.html">embedded Jetty server</a> through gradle to satisfy this interface.<br />
</p> <br />
<em>web/build.gradle</em><br />
<div style="
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin"> <div style="font-family: courier new; width: 80em; font-size: 11pt;"><span style="color: rgb(0,0,0);">....</span><br />
<span style="color: rgb(0,0,0);">apply</span> <span style="color: rgb(0,0,0);">plugin:</span> <span style="color: rgb(255,0,204);">'jetty'</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">stopPort</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(205,50,0);">8001</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">safeWord</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(255,0,204);">'banana'</span><br />
<br />
<span style="color: rgb(0,0,0);">task</span> <span style="color: rgb(0,0,0);">webStart(dependsOn:</span> <span style="color: rgb(255,0,204);">'grails-war'</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);"><<</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">jettyRunWar</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">tasks.getByPath(</span><span style="color: rgb(255,0,204);">'jettyRunWar'</span><span style="color: rgb(0,0,0);">)</span><br />
<span style="color: rgb(0,0,0);">jettyRunWar.webApp</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(151,44,120);">new</span> <span style="color: rgb(0,0,0);">File(projectDir,</span> <span style="color: rgb(255,0,204);">"target/course_registry-${version}.war"</span><span style="color: rgb(0,0,0);">)</span><br />
<span style="color: rgb(0,0,0);">jettyRunWar.contextPath</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(255,0,204);">'course_registry'</span><br />
<span style="color: rgb(0,0,0);">jettyRunWar.daemon</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(151,44,120);">true</span><br />
<span style="color: rgb(0,0,0);">jettyRunWar.stopPort</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">stopPort</span><br />
<span style="color: rgb(0,0,0);">jettyRunWar.stopKey</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">safeWord</span><br />
<span style="color: rgb(0,0,0);">jettyRunWar.execute()</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="color: rgb(0,0,0);">task</span> <span style="color: rgb(0,0,0);">webStop</span> <span style="color: rgb(0,0,0);"><<</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">jettyStop</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">tasks.getByPath(</span><span style="color: rgb(255,0,204);">'jettyStop'</span><span style="color: rgb(0,0,0);">)</span><br />
<span style="color: rgb(0,0,0);">jettyStop.stopPort</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">stopPort</span><br />
<span style="color: rgb(0,0,0);">jettyStop.stopKey</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">safeWord</span><br />
<span style="color: rgb(0,0,0);">jettyStop.execute()</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">....</span><br />
</div> </div> <br />
<p> The first specification should now be satisfied.<br />
</p> <div style="
overflow: auto;
padding: 1em;
background-color: black;
color: white;
border-style: dashed;
border-width: thin"> <span style="font-family: courier new; font-size: 11pt;"><br />
<span style="color: green;">course_registry $></span> gradle test --info<br />
....<br />
Started Jetty Server<br />
Gradle Worker 1 executing tests.<br />
Test a user is greeted with an intro screen(timezra.course_registry.TeacherRegistrationSpec) PASSED<br />
Gradle Worker 1 finished executing tests.<br />
....<br />
</span><br />
</div> <br />
<strong>NB:</strong> The Jetty plugin must be applied before the grails plugin, or else you will see an error similar to the following:<br />
<div style="
overflow: auto;
padding: 1em;
background-color: black;
color: white;
border-style: dashed;
border-width: thin"> <div style="font-family: courier new; width: 80em; font-size: 11pt;"> <span style="color:red;">FAILURE: Build failed with an exception.</span><br />
<br />
* Where:<br />
Build file '/path/to/course_registry/web/build.gradle' line: 38<br />
<br />
* What went wrong:<br />
A problem occurred evaluating project ':web'.<br />
Cause: Cannot add task ':web:clean' as a task with that name already exists.<br />
<br />
* Try:<br />
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.<br />
<br />
<span style="color:red;">BUILD FAILED</span><br />
<br />
Total time: 7.624 secs<br />
</div> </div> <br />
<p> Adding another test for our second acceptance criterion should be straightforward now that our infrastructure is in place. <br />
</p> <em>timezra/course_registry/TeacherRegistrationSpec.groovy</em><br />
<div style="
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin"> <div style="font-family: courier new; width: 80em; font-size: 11pt;"> <span style="color: rgb(0,0,0);">....</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(255,0,204);">"a user can register as a teacher"</span><span style="color: rgb(0,0,0);">()</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">when:</span><br />
<span style="color: rgb(0,0,0);">driver.get</span> <span style="color: rgb(255,0,204);">"http://localhost:8080/course_registry"</span><br />
<span style="color: rgb(0,0,0);">WebElement</span> <span style="color: rgb(0,0,0);">teacherLink</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">driver.findElement(By.id(</span><span style="color: rgb(255,0,204);">'teacher_link'</span><span style="color: rgb(0,0,0);">))</span><br />
<span style="color: rgb(0,0,0);">teacherLink.click()</span><br />
<span style="color: rgb(0,0,0);">WebElement</span> <span style="color: rgb(0,0,0);">name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">driver.findElement(By.id(</span><span style="color: rgb(255,0,204);">'name'</span><span style="color: rgb(0,0,0);">))</span><br />
<span style="color: rgb(0,0,0);">type</span> <span style="color: rgb(0,0,0);">name,</span> <span style="color: rgb(255,0,204);">'John Doe'</span><br />
<span style="color: rgb(0,0,0);">WebElement</span> <span style="color: rgb(0,0,0);">email</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">driver.findElement(By.id(</span><span style="color: rgb(255,0,204);">'email'</span><span style="color: rgb(0,0,0);">))</span><br />
<span style="color: rgb(0,0,0);">type</span> <span style="color: rgb(0,0,0);">email,</span> <span style="color: rgb(255,0,204);">"${UUID.</span><span style="color: rgb(0,0,0); font-style: italic;">randomUUID</span><span style="color: rgb(255,0,204);">()}@rutgers.edu"</span><br />
<span style="color: rgb(0,0,0);">WebElement</span> <span style="color: rgb(0,0,0);">password</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">driver.findElement(By.id(</span><span style="color: rgb(255,0,204);">'password'</span><span style="color: rgb(0,0,0);">))</span><br />
<span style="color: rgb(0,0,0);">type</span> <span style="color: rgb(0,0,0);">password,</span> <span style="color: rgb(255,0,204);">'1234567'</span><br />
<span style="color: rgb(0,0,0);">WebElement</span> <span style="color: rgb(0,0,0);">create</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">driver.findElement(By.id(</span><span style="color: rgb(255,0,204);">'create'</span><span style="color: rgb(0,0,0);">))</span><br />
<span style="color: rgb(0,0,0);">create.click()</span><br />
<br />
<span style="color: rgb(0,0,0);">then:</span><br />
<span style="color: rgb(0,0,0);">driver.title</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(255,0,204);">'Show Teacher'</span><br />
<span style="color: rgb(0,0,0);">driver.findElement(By.className(</span><span style="color: rgb(255,0,204);">'message'</span><span style="color: rgb(0,0,0);">)).text</span> <span style="color: rgb(0,0,0);">==~</span> <span style="color: rgb(0,0,0);">/Teacher</span> <span style="color: rgb(0,0,0);">\d+</span> <span style="color: rgb(0,0,0);">created/</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">type(field,</span> <span style="color: rgb(0,0,0);">text)</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">field.clear()</span><br />
<span style="color: rgb(0,0,0);">field.sendKeys</span> <span style="color: rgb(0,0,0);">text</span><br />
<span style="color: rgb(0,0,0);">}</span></div> </div> <br />
<p> We can satisfy this specification by generating a Grails <em>Teacher</em> domain object with fields for the name, email and password, along with a Grails controller that uses dynamic scaffolding to generate the view and actions available, and by adding a link to the scaffolded <em>Create Teacher</em> page on our <em>web/grails-app/views/index.gsp</em>. Since the point of this tutorial is not to cover basic Grails development, we do not need to go into those specifics here, but sample code can be found on the <a href="https://github.com/timezra/course_registry">project site</a> or in any <a href="http://grails.org/Tutorials">Grails tutorial</a> for further reference.<br />
</p> <br />
<h4>Page Objects</h4> <p> Before we get too far with automating our acceptance criteria, we should begin to look towards a more abstract representation of the testable components of our application. From the second acceptance test above, we can already see patterns emerging. For example, when we navigate to a particular page, it would be convenient to identify that we are on the correct page, perhaps by its title. It would also be convenient to represent each view in the application as its own object, and each view could encapsulate its specific <em>WebElement</em>s. Finally, there is a small set of actions available for any <em>WebElement</em> on a page, and it would be helpful to build these actions into a testing DSL. Fortunately, by combining the <a href="http://code.google.com/p/selenium/wiki/PageObjects">Page Object</a> pattern and Groovy's dynamic language features, we can achieve all these goals with a minimal amount of code. <br />
</p> <p> As we are satisfying the specifications for all the <a href="#user_stories">acceptance criteria</a>, a base <a href="http://code.google.com/p/selenium/wiki/PageObjects">Page Object</a> emerges.<br />
</p> <em>specifications/src/test/groovy/timezra/course_registry/pages/CourseRegistryPage.groovy</em><br />
<div style="
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin"> <div style="font-family: courier new; width: 80em; font-size: 11pt;"> <span style="font-weight: bold; color: rgb(151,44,120);">package</span> <span style="color: rgb(0,0,0);">timezra.course_registry.pages</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">import</span> <span style="font-weight: bold; color: rgb(151,44,120);">static</span> <span style="color: rgb(0,0,0);">org.apache.commons.lang.StringUtils.splitByCharacterTypeCamelCase</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">import</span> <span style="color: rgb(0,0,0);">org.openqa.selenium.WebDriver</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">import</span> <span style="color: rgb(0,0,0);">org.openqa.selenium.WebElement</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">import</span> <span style="color: rgb(0,0,0);">org.openqa.selenium.support.FindBy</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">import</span> <span style="color: rgb(0,0,0);">org.openqa.selenium.support.PageFactory</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">import</span> <span style="color: rgb(0,0,0);">org.openqa.selenium.support.ui.Select</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">abstract</span> <span style="font-weight: bold; color: rgb(151,44,120);">class</span> <span style="color: rgb(0,0,0);">CourseRegistryPage</span> <span style="color: rgb(0,0,0);">{</span><br />
<br />
<span style="color: rgb(0,0,0);">WebDriver</span> <span style="color: rgb(0,0,0);">driver</span><br />
<br />
<span style="color: rgb(70,70,70);">@FindBy</span><span style="color: rgb(0,0,0);">(className</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(255,0,204);">"message"</span><span style="color: rgb(0,0,0);">)</span><br />
<span style="color: rgb(0,0,0);">WebElement</span> <span style="color: rgb(0,0,0);">message</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">static</span> <span style="color: rgb(0,0,0);"><T</span> <span style="font-weight: bold; color: rgb(151,44,120);">extends</span> <span style="color: rgb(0,0,0);">CourseRegistryPage></span> <span style="color: rgb(0,0,0);">T</span> <span style="color: rgb(0,0,0);">goTo(String</span> <span style="color: rgb(0,0,0);">address,</span> <span style="color: rgb(0,0,0);">WebDriver</span> <span style="color: rgb(0,0,0);">driver,</span> <span style="color: rgb(0,0,0);">Class<T></span> <span style="color: rgb(0,0,0);">page)</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">driver.get</span> <span style="color: rgb(0,0,0);">address</span><br />
<span style="color: rgb(0,0,0);">PageFactory.initElements</span> <span style="color: rgb(0,0,0);">driver,</span> <span style="color: rgb(0,0,0);">page</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="color: rgb(0,0,0);">CourseRegistryPage(WebDriver</span> <span style="color: rgb(0,0,0);">driver)</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">this</span><span style="color: rgb(0,0,0);">.driver</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">driver</span><br />
<span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">title</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">splitByCharacterTypeCamelCase(getClass().simpleName).</span><span style="color: rgb(102,204,255);">join</span> <span style="color: rgb(255,0,204);">' '</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">if</span><span style="color: rgb(0,0,0);">(!title.equals(driver.title))</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">throw</span> <span style="font-weight: bold; color: rgb(151,44,120);">new</span> <span style="color: rgb(0,0,0);">IllegalStateException(</span><span style="color: rgb(255,0,204);">"Should be on page '${title}' but was on page '${driver.title}' instead"</span><span style="color: rgb(0,0,0);">)</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">methodMissing(String</span> <span style="color: rgb(0,0,0);">name,</span> <span style="color: rgb(0,0,0);">args)</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">m</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">if</span><span style="color: rgb(0,0,0);">((m</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">name</span> <span style="color: rgb(0,0,0);">=~</span> <span style="color: rgb(0,0,0);">/click_(\w+)/))</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">webElement</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(151,44,120);">this</span><span style="color: rgb(0,0,0);">.</span><span style="color: rgb(255,0,204);">"${m[0][1]}"</span><br />
<span style="color: rgb(0,0,0);">webElement.click()</span><br />
<span style="color: rgb(0,0,0);">PageFactory.initElements</span> <span style="color: rgb(0,0,0);">driver,</span> <span style="color: rgb(0,0,0);">args[</span><span style="color: rgb(205,50,0);">0</span><span style="color: rgb(0,0,0);">]</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">else</span> <span style="font-weight: bold; color: rgb(151,44,120);">if</span><span style="color: rgb(0,0,0);">((m</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">name</span> <span style="color: rgb(0,0,0);">=~</span> <span style="color: rgb(0,0,0);">/type_(\w+)/))</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">webElement</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(151,44,120);">this</span><span style="color: rgb(0,0,0);">.</span><span style="color: rgb(255,0,204);">"${m[0][1]}"</span><br />
<span style="color: rgb(0,0,0);">webElement.clear()</span><br />
<span style="color: rgb(0,0,0);">webElement.sendKeys</span> <span style="color: rgb(0,0,0);">args[</span><span style="color: rgb(205,50,0);">0</span><span style="color: rgb(0,0,0);">]</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">else</span> <span style="font-weight: bold; color: rgb(151,44,120);">if</span><span style="color: rgb(0,0,0);">((m</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">name</span> <span style="color: rgb(0,0,0);">=~</span> <span style="color: rgb(0,0,0);">/choose_(\w+)/))</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">webElement</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(151,44,120);">this</span><span style="color: rgb(0,0,0);">.</span><span style="color: rgb(255,0,204);">"${m[0][1]}"</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">select</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(151,44,120);">new</span> <span style="color: rgb(0,0,0);">Select(webElement)</span><br />
<span style="color: rgb(0,0,0);">select.selectByVisibleText</span> <span style="color: rgb(0,0,0);">args[</span><span style="color: rgb(205,50,0);">0</span><span style="color: rgb(0,0,0);">]</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">else</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">throw</span> <span style="font-weight: bold; color: rgb(151,44,120);">new</span> <span style="color: rgb(0,0,0);">MissingMethodException(name,</span> <span style="color: rgb(0,0,0);">getClass(),</span> <span style="color: rgb(0,0,0);">args)</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
</div> </div> <p>NB: The constructor verifies that the page is correct by comparing the class name to the page title; in addition, the static <em>goTo</em> method demonstrates how to use the <em>PageFactory</em> for initializing a <a href="http://code.google.com/p/selenium/wiki/PageObjects">Page Object</a>; the <em>methodMissing</em> declaration also showcases Groovy's ability to call dynamic methods based on the combination of the <em>click</em>, <em>type</em> and <em>choose</em> actions with individual <em>WebElement</em> names. Such phrases become first-class elements of the testing DSL.</p> <br />
<p> We can see the use of <em>WebElement</em> injection and dynamic methods in action with a <em>CreateUser</em> page that serves as the base for the <em>CreateTeacher</em> and <em>CreateStudent</em> pages.<br />
</p> <br />
<em>specifications/src/test/groovy/timezra/course_registry/pages/CreateUser.groovy</em><br />
<div style="
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin"> <span style="font-family: courier new; font-size: 11pt;"><br />
<span style="font-weight: bold; color: rgb(151,44,120);">package</span> <span style="color: rgb(0,0,0);">timezra.course_registry.pages</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">import</span> <span style="color: rgb(0,0,0);">groovy.transform.InheritConstructors</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">import</span> <span style="color: rgb(0,0,0);">org.openqa.selenium.WebDriver</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">import</span> <span style="color: rgb(0,0,0);">org.openqa.selenium.WebElement</span><br />
<br />
<span style="color: rgb(70,70,70);">@InheritConstructors</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">abstract</span> <span style="font-weight: bold; color: rgb(151,44,120);">class</span> <span style="color: rgb(0,0,0);">CreateUser</span> <span style="font-weight: bold; color: rgb(151,44,120);">extends</span> <span style="color: rgb(0,0,0);">CourseRegistryPage</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">WebElement</span> <span style="color: rgb(0,0,0);">name</span><br />
<span style="color: rgb(0,0,0);">WebElement</span> <span style="color: rgb(0,0,0);">email</span><br />
<span style="color: rgb(0,0,0);">WebElement</span> <span style="color: rgb(0,0,0);">password</span><br />
<span style="color: rgb(0,0,0);">WebElement</span> <span style="color: rgb(0,0,0);">create</span><br />
<br />
<span style="color: rgb(0,0,0);">CreateUser(WebDriver</span> <span style="color: rgb(0,0,0);">driver)</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">super</span><span style="color: rgb(0,0,0);">(driver)</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">protected</span> <span style="color: rgb(0,0,0);"><T></span> <span style="color: rgb(0,0,0);">T</span> <span style="color: rgb(0,0,0);">register(name,</span> <span style="color: rgb(0,0,0);">email,</span> <span style="color: rgb(0,0,0);">password,</span> <span style="color: rgb(0,0,0);">Class<T></span> <span style="color: rgb(0,0,0);">nextPage)</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">type_name</span> <span style="color: rgb(0,0,0);">name</span><br />
<span style="color: rgb(0,0,0);">type_email</span> <span style="color: rgb(0,0,0);">email</span><br />
<span style="color: rgb(0,0,0);">type_password</span> <span style="color: rgb(0,0,0);">password</span><br />
<span style="color: rgb(0,0,0);">click_create</span> <span style="color: rgb(0,0,0);">nextPage</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
</span><br />
</div><br />
<h4>Other Browsers</h4> So far, we have done all our testing with a single <em>WebDriver</em>, i.e., the <em>FirefoxDriver</em>. For simple testing, a single driver works fine, but if we wish to ensure that our website works in multiple browsers, we will need to configure our tests to use multiple <em>WebDriver</em>s. Fortunately, since we are using Gradle to manage our dependencies, the <em>InternetExplorerDriver</em> and <a href="http://code.google.com/p/selenium/wiki/ChromeDriver"><em>ChromeDriver</em></a> should be available to us automatically, along with the <em>AndroidDriver</em> and <em>IPhoneDriver</em> for testing our application on mobile devices. In addition, an <a href="http://code.google.com/p/selenium/wiki/OperaDriver"><em>OperaDriver</em></a> is also available.<br />
<p> <strong>NB:</strong> Some of these drivers require that additional platform-specific software be installed, so please read the project pages for documentation on additional requirements.<br />
</p> <br />
<p> Configuring our specifications to use multiple <em>WebDriver</em>s should just be a matter of <a href="http://code.google.com/p/spock/wiki/Parameterizations">parameterizing each Spock feature</a>.<br />
</p> <p> <strong>NB:</strong> Unlike JUnit tests which are parameterized by fixture, Spock specifications are parameterized per feature.<br />
</p> <br />
<p> We will modify our <em>TeacherRegistrationSpec</em> to use the Spock <em>where:</em> block for parameterization, we will configure multiple <em>WebDriver</em>s, and we will <em>share</em> the instance <em>driver</em> field among the parameterized features. <br />
</p> <em>timezra/course_registry/TeacherRegistrationSpec.groovy</em><br />
<div style="
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin"> <div style="font-family: courier new; width: 80em; font-size: 11pt;"> <span style="font-weight: bold; color: rgb(151,44,120);">class</span> <span style="color: rgb(0,0,0);">TeacherRegistrationSpec</span> <span style="font-weight: bold; color: rgb(151,44,120);">extends</span> <span style="color: rgb(0,0,0);">Specification</span> <span style="color: rgb(0,0,0);">{</span><br />
<br />
<span style="color: rgb(70,70,70);">@Shared</span><br />
<span style="color: rgb(0,0,0);">WebDriver</span> <span style="color: rgb(0,0,0);">driver</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">setup()</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">driver.manage().timeouts().implicitlyWait</span> <span style="color: rgb(205,50,0);">10</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">SECONDS</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">cleanup()</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">driver.quit()</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(255,0,204);">"a user is greeted with an intro screen"</span><span style="color: rgb(0,0,0);">()</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">when:</span><br />
<span style="color: rgb(0,0,0);">....</span><br />
<br />
<span style="color: rgb(0,0,0);">then:</span><br />
<span style="color: rgb(0,0,0);">....</span><br />
<br />
<span style="color: rgb(0,0,0);">where:</span><br />
<span style="color: rgb(0,0,0);">browser</span> <span style="color: rgb(0,0,0);"><<</span> <span style="color: rgb(0,0,0);">browsers()</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(255,0,204);">"a user can register as a teacher"</span><span style="color: rgb(0,0,0);">()</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">when:</span><br />
<span style="color: rgb(0,0,0);">....</span><br />
<br />
<span style="color: rgb(0,0,0);">then:</span><br />
<span style="color: rgb(0,0,0);">....</span><br />
<br />
<span style="color: rgb(0,0,0);">where:</span><br />
<span style="color: rgb(0,0,0);">browser</span> <span style="color: rgb(0,0,0);"><<</span> <span style="color: rgb(0,0,0);">browsers()</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="color: rgb(0,0,0);">....</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">protected</span> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">browsers()</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">System.setProperty(</span><span style="color: rgb(255,0,204);">"webdriver.chrome.driver"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(255,0,204);">"/path/to/chromedriver"</span><span style="color: rgb(0,0,0);">)</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">drivers</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">[</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">new</span> <span style="color: rgb(0,0,0);">HtmlUnitDriver(),</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">new</span> <span style="color: rgb(0,0,0);">FirefoxDriver(),</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">new</span> <span style="color: rgb(0,0,0);">ChromeDriver()</span><br />
<span style="color: rgb(0,0,0);">]</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">new</span> <span style="color: rgb(0,0,0);">Browsers(spec:</span> <span style="font-weight: bold; color: rgb(151,44,120);">this</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">delegate:</span> <span style="color: rgb(0,0,0);">drivers.iterator())</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">private</span> <span style="font-weight: bold; color: rgb(151,44,120);">static</span> <span style="font-weight: bold; color: rgb(151,44,120);">final</span> <span style="font-weight: bold; color: rgb(151,44,120);">class</span> <span style="color: rgb(0,0,0);">Browsers</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(70,70,70);">@Delegate</span> <span style="color: rgb(0,0,0);">Iterator<WebDriver></span> <span style="color: rgb(0,0,0);">delegate</span><br />
<span style="color: rgb(0,0,0);">TeacherRegistrationSpec</span> <span style="color: rgb(0,0,0);">spec</span><br />
<br />
<span style="color: rgb(70,70,70);">@Override</span> <span style="color: rgb(0,0,0);">WebDriver</span> <span style="color: rgb(102,204,255);">next</span><span style="color: rgb(0,0,0);">()</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">spec.driver</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">delegate.</span><span style="color: rgb(102,204,255);">next</span><span style="color: rgb(0,0,0);">()</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
</div> </div><br />
<h4>Testing In The Cloud</h4> <p> Now that our specifications are running through multiple browsers on a single machine, we can move a step further towards testing multiple browser versions on multiple OSes with cloud-based services such as <a href="http://saucelabs.com/">Sauce Labs</a>. For such a powerful service, the configuration changes to our existing application are surprisingly simple. We will modify our <em>TeacherRegistrationSpec</em> to use a <em>RemoteWebDriver</em> for the specific browser and OS combination we would like to test along with our Sauce Labs username and API key as described in the <a href="http://saucelabs.com/docs/ondemand/getting-started/env/java/se2/mac">Sauce OnDemand documentation</a>. We will also need to add a Gradle plugin to start <em>SauceConnect</em> from the build, just as we start our web application before running acceptance tests. Finally, we should ensure that all references to <em>localhost</em> in our application are changed to the IP address of the machine where we will be running our tests; otherwise, we might see the <em>SauceConnect</em> proxy freeze (you might have a different experience, and this freezing might just be attributable to the Gremlins in my machine). <br />
</p> <br />
<em>timezra/course_registry/TeacherRegistrationSpec.groovy</em><br />
<div style="
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin"> <div style="font-family: courier new; width: 80em; font-size: 11pt;"> <span style="font-weight: bold; color: rgb(151,44,120);">class</span> <span style="color: rgb(0,0,0);">TeacherRegistrationSpec</span> <span style="font-weight: bold; color: rgb(151,44,120);">extends</span> <span style="color: rgb(0,0,0);">Specification</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">....</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(255,0,204);">"a user is greeted with an intro screen"</span><span style="color: rgb(0,0,0);">()</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">when:</span><br />
<span style="color: rgb(0,0,0);">driver.get</span> <span style="color: rgb(255,0,204);">"http://<your.ip.address>:8080/course_registry"</span><br />
<span style="color: rgb(0,0,0);">....</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(255,0,204);">"a user can register as a teacher"</span><span style="color: rgb(0,0,0);">()</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">when:</span><br />
<span style="color: rgb(0,0,0);">driver.get</span> <span style="color: rgb(255,0,204);">"http://<your.ip.address>:8080/course_registry/"</span><br />
<span style="color: rgb(0,0,0);">....</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">....</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">protected</span> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">browsers()</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">capabilities</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">DesiredCapabilities.internetExplorer()</span><br />
<span style="color: rgb(0,0,0);">capabilities.setCapability(</span><span style="color: rgb(255,0,204);">"version"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(255,0,204);">"7"</span><span style="color: rgb(0,0,0);">)</span><br />
<span style="color: rgb(0,0,0);">capabilities.setCapability(</span><span style="color: rgb(255,0,204);">"platform"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">Platform.XP)</span><br />
<span style="color: rgb(0,0,0);">capabilities.setCapability(</span><span style="color: rgb(255,0,204);">"name"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(255,0,204);">"Testing Teacher Registration in Sauce"</span><span style="color: rgb(0,0,0);">)</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">sauceDriver</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(151,44,120);">new</span> <span style="color: rgb(0,0,0);">RemoteWebDriver(</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">new</span> <span style="color: rgb(0,0,0);">URL(</span><br />
<span style="color: rgb(255,0,204);">"http://<username>:<apiKey>@ondemand.saucelabs.com:80/wd/hub"</span><span style="color: rgb(0,0,0);">),</span><br />
<span style="color: rgb(0,0,0);">capabilities)</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">drivers</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">[sauceDriver]</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">new</span> <span style="color: rgb(0,0,0);">Browsers(spec:</span> <span style="font-weight: bold; color: rgb(151,44,120);">this</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">delegate:</span> <span style="color: rgb(0,0,0);">drivers.iterator())</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">....</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
</div> </div> <br />
<em>course_registry/specifications/build.gradle</em><br />
<div style="
overflow: auto;
padding: 1em;
background-color: white;
border-style: dashed;
border-width: thin"> <div style="font-family: courier new; width: 80em; font-size: 11pt;"> <span style="font-weight: bold; color: rgb(151,44,120);">import</span> <span style="color: rgb(0,0,0);">java.util.concurrent.Executors</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">import</span> <span style="color: rgb(0,0,0);">java.util.concurrent.ExecutorService</span><br />
<span style="color: rgb(0,0,0);">....</span><br />
<span style="color: rgb(0,0,0);">repositories</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">....</span><br />
<span style="color: rgb(0,0,0);">mavenRepo</span> <span style="color: rgb(0,0,0);">url:</span> <span style="color: rgb(255,0,204);">"https://repository-saucelabs.forge.cloudbees.com/release"</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="color: rgb(0,0,0);">dependencies</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">....</span><br />
<span style="color: rgb(0,0,0);">runtime</span> <span style="color: rgb(0,0,0);">group:</span> <span style="color: rgb(255,0,204);">'com.saucelabs'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">name:</span> <span style="color: rgb(255,0,204);">'sauce-connect'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">version:</span> <span style="color: rgb(255,0,204);">'3.0.18'</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="color: rgb(0,0,0);">apply</span> <span style="color: rgb(0,0,0);">plugin:</span> <span style="color: rgb(0,0,0);">SauceConnect</span><br />
<br />
<span style="color: rgb(0,0,0);">sauceConfig</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">username</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(255,0,204);">'<username>'</span><br />
<span style="color: rgb(0,0,0);">apiKey</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(255,0,204);">'<apiKey>'</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="color: rgb(0,0,0);">test.dependsOn</span> <span style="color: rgb(255,0,204);">':web:webStart'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(255,0,204);">'sauceConnect'</span><br />
<br />
<span style="color: rgb(0,0,0);">gradle.taskGraph.afterTask</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(0,0,0);">Task</span> <span style="color: rgb(0,0,0);">task,</span> <span style="color: rgb(0,0,0);">TaskState</span> <span style="color: rgb(0,0,0);">state</span> <span style="color: rgb(0,0,0);">-></span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">if</span><span style="color: rgb(0,0,0);">(</span><span style="color: rgb(255,0,204);">':specifications:test'</span><span style="color: rgb(0,0,0);">.equals(task.path))</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">tasks.getByPath(</span><span style="color: rgb(255,0,204);">'sauceDisconnect'</span><span style="color: rgb(0,0,0);">).execute()</span><br />
<span style="color: rgb(0,0,0);">project(</span><span style="color: rgb(255,0,204);">':web'</span><span style="color: rgb(0,0,0);">).tasks.getByPath(</span><span style="color: rgb(255,0,204);">'webStop'</span><span style="color: rgb(0,0,0);">).execute()</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">class</span> <span style="color: rgb(0,0,0);">SauceConnect</span> <span style="font-weight: bold; color: rgb(151,44,120);">implements</span> <span style="color: rgb(0,0,0);">Plugin<Project></span> <span style="color: rgb(0,0,0);">{</span><br />
<br />
<span style="color: rgb(0,0,0);">ExecutorService</span> <span style="color: rgb(0,0,0);">executor</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">Executors.newFixedThreadPool(</span><span style="color: rgb(205,50,0);">2</span><span style="color: rgb(0,0,0);">)</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="font-weight: bold; color: rgb(151,44,120);">void</span> <span style="color: rgb(0,0,0);">apply(Project</span> <span style="color: rgb(0,0,0);">project)</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">project.extensions.sauceConfig</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(151,44,120);">new</span> <span style="color: rgb(0,0,0);">SauceConnectExtension()</span><br />
<br />
<span style="color: rgb(0,0,0);">project.task(</span><span style="color: rgb(255,0,204);">'sauceConnect'</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);"><<</span> <span style="color: rgb(0,0,0);">{</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">output</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(151,44,120);">new</span> <span style="color: rgb(0,0,0);">PipedOutputStream()</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">input</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(151,44,120);">new</span> <span style="color: rgb(0,0,0);">PipedInputStream(output)</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">reader</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(151,44,120);">new</span> <span style="color: rgb(0,0,0);">BufferedReader(</span><span style="font-weight: bold; color: rgb(151,44,120);">new</span> <span style="color: rgb(0,0,0);">InputStreamReader(input))</span><br />
<br />
<span style="color: rgb(0,0,0);">executor.execute</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(102,204,255);">println</span> <span style="color: rgb(255,0,204);">"Connecting to Sauce Labs as ${project.sauceConfig.username} with key ${project.sauceConfig.apiKey}...."</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">try</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">project.javaexec</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">main</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(255,0,204);">'com.saucelabs.sauceconnect.SauceConnect'</span><br />
<span style="color: rgb(0,0,0);">classpath</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">project.sourceSets.main.runtimeClasspath</span><br />
<span style="color: rgb(0,0,0);">args</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">[project.sauceConfig.username,</span> <span style="color: rgb(0,0,0);">project.sauceConfig.apiKey]</span><br />
<span style="color: rgb(0,0,0);">standardOutput</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">output</span><br />
<span style="color: rgb(0,0,0);">}</span> <br />
<span style="color: rgb(0,0,0);">}</span> <span style="font-weight: bold; color: rgb(151,44,120);">catch</span><span style="color: rgb(0,0,0);">(Exception</span> <span style="color: rgb(0,0,0);">ignored)</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(63,127,95);">// Executor has been shutdown<br />
</span> <span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">boolean</span> <span style="color: rgb(0,0,0);">okToStart</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(151,44,120);">false</span><br />
<span style="color: rgb(0,0,0);">executor.execute</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">nextLine</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">try</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">while</span><span style="color: rgb(0,0,0);">((nextLine</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">reader.readLine())</span> <span style="color: rgb(0,0,0);">!=</span> <span style="font-weight: bold; color: rgb(151,44,120);">null</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(102,204,255);">println</span> <span style="color: rgb(0,0,0);">nextLine</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">if</span><span style="color: rgb(0,0,0);">(!okToStart)</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">if</span><span style="color: rgb(0,0,0);">(nextLine</span> <span style="color: rgb(0,0,0);">=~</span> <span style="color: rgb(0,0,0);">/Please</span> <span style="color: rgb(0,0,0);">wait</span> <span style="font-weight: bold; color: rgb(151,44,120);">for</span> <span style="color: rgb(255,0,204);">"You may start your tests"</span> <span style="color: rgb(0,0,0);">to</span> <span style="color: rgb(0,0,0);">start</span> <span style="color: rgb(0,0,0);">your</span> <span style="color: rgb(0,0,0);">tests/)</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">continue</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">else</span> <span style="font-weight: bold; color: rgb(151,44,120);">if</span><span style="color: rgb(0,0,0);">(nextLine</span> <span style="color: rgb(0,0,0);">=~</span> <span style="color: rgb(0,0,0);">/You</span> <span style="color: rgb(0,0,0);">may</span> <span style="color: rgb(0,0,0);">start</span> <span style="color: rgb(0,0,0);">your</span> <span style="color: rgb(0,0,0);">tests/)</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">okToStart</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(151,44,120);">true</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">}</span> <span style="font-weight: bold; color: rgb(151,44,120);">catch</span><span style="color: rgb(0,0,0);">(Exception</span> <span style="color: rgb(0,0,0);">ignored)</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(63,127,95);">// Executor has been shutdown<br />
</span> <span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="font-weight: bold; color: rgb(151,44,120);">while</span><span style="color: rgb(0,0,0);">(!okToStart)</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">Thread.sleep</span> <span style="color: rgb(205,50,0);">250</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="color: rgb(0,0,0);">project.task(</span><span style="color: rgb(255,0,204);">'sauceDisconnect'</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);"><<</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(102,204,255);">println</span> <span style="color: rgb(255,0,204);">"Disconnecting from Sauce Labs...."</span><br />
<span style="color: rgb(0,0,0);">executor.shutdownNow()</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
<br />
<span style="font-weight: bold; color: rgb(151,44,120);">class</span> <span style="color: rgb(0,0,0);">SauceConnectExtension</span> <span style="color: rgb(0,0,0);">{</span><br />
<span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">username</span><br />
<span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">apiKey</span><br />
<span style="color: rgb(0,0,0);">}</span><br />
</div> </div> <br />
<h4>Conclusion</h4> <p> This post took us through the definition of user stories for a small website, the setup of a Gradle project for automating the website build and the run of its corresponding acceptance tests, the creation of our first <em>WebDriver</em>-based Spock specification for our acceptance criteria and the fulfillment of that spec with a Grails 2.0 application, the use of Selenium PageObjects to create abstract representations of our web pages before those web pages are even written, all the way to the creation of a Gradle plugin for running our acceptance tests on various browser/OS combinations in Sauce Labs. Each of those items in itself is worthy of a tutorial series. The combination of all these elements demonstrates with a remarkably small amount of configuration and code the type of robust and scalable ATDD infrastructure that is possible and should be at the core of any enterprise web application.<br />
</p></body><br />
</html>Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com44tag:blogger.com,1999:blog-106449775438946661.post-80335558299003013672011-11-10T22:59:00.000-08:002011-11-11T06:51:41.811-08:00Trampoline and MemoizeTrampoline and Memoize<br /><br /><h4>Goal</h4><br />Groovy 1.8 introduces two new closure functions. Memoization is the automatic caching of closure results. Trampolining permits a form of declarative tail-call optimization. This article introduces the two concepts and demonstrates how to combine them in order to create cached, tail-recursive closures.<br /><br /><h4>tl;dr</h4><br />The example code from this article is <a href="https://github.com/timezra/groovy-trampoline-memoize-specs">available on github</a>.<br /><br /><h4>Simple Memoization</h4><br />Creating a closure that caches the result of some calculation is as easy as appending <em>.memoize()</em> or one of the alternate <em>memoize...(...)</em> methods that allows more fine-grained control over cache sizes to a closure declaration. One benefit of memoization includes the caching of results of long-running calculations that have no side effects. Memory leaks are a potential pitfall, which is why a maximum cache size should generally be prefered.<br />The specification below contains a closure with a side-effect. This side effect happens just once, despite the closure being invoked twice.<br /><br /><em>SimpleMemoizationSpec.groovy</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><span style="font-weight: bold; color: rgb(151,44,120);">package</span> <span style="color: rgb(0,0,0);">timezra.groovy.trampoline_memoize</span><br /><br /><span style="font-weight: bold; color: rgb(151,44,120);">class</span> <span style="color: rgb(0,0,0);">SimpleMemoizationSpec</span> <span style="font-weight: bold; color: rgb(151,44,120);">extends</span> <span style="color: rgb(0,0,0);">spock.lang.Specification</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(151,44,120);">int</span> <span style="color: rgb(102,204,255);">count</span><br /><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">identity</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(102,204,255);">count</span><span style="color: rgb(0,0,0);">++</span><br /> <span style="color: rgb(102,204,255);">it</span><br /> <span style="color: rgb(0,0,0);">}.memoize()</span><br /><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(42,0,255);">"each call should be cached"</span><span style="color: rgb(0,0,0);">()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">when:</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">first</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">identity</span> <span style="color: rgb(205,50,0);">0</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">second</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">identity</span> <span style="color: rgb(205,50,0);">0</span><br /><br /> <span style="color: rgb(0,0,0);">then:</span><br /> <span style="color: rgb(102,204,255);">count</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">1</span><br /> <span style="color: rgb(0,0,0);">first</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">second</span><br /> <span style="color: rgb(0,0,0);">second</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">0</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br /><h4>Recursive Memoization</h4><br />Suppose we want to memoize the results of a recursive closure call. For example, we can unroll the call tree of this naive implementation of the fibonacci function. <br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(0,0,0);">n</span> <span style="color: rgb(0,0,0);">-></span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">if</span><span style="color: rgb(0,0,0);">(n</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">0</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(205,50,0);">0</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">else</span> <span style="font-weight: bold; color: rgb(151,44,120);">if</span><span style="color: rgb(0,0,0);">(n</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">1</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(205,50,0);">1</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">else</span> <span style="color: rgb(0,0,0);">fib(n-</span><span style="color: rgb(205,50,0);">1</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">fib(n-</span><span style="color: rgb(205,50,0);">2</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">}</span></span><br /></div><br />The call trace for the fourth fibonacci number looks like this.<br /><div style="overflow:auto;padding:5px;background-color:silver;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><span style="font-family: courier new; font-size: 11pt;"><br /> <span style="color: rgb(0,0,0);">___________fib</span> <span style="color: rgb(205,50,0);">4</span><span style="color: rgb(0,0,0);">___________</span><br /> <span style="color: rgb(0,0,0);">/</span> <span style="color: rgb(0,0,0);">\</span><br /> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">3</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">2</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">2</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">1</span><br /> <span style="color: rgb(0,0,0);">/</span> <span style="color: rgb(0,0,0);">\</span> <span style="color: rgb(0,0,0);">/</span><br /> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">2</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">1</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">2</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">1</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">1</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">0</span><br /> <span style="color: rgb(0,0,0);">/</span><br /><span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">1</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">0</span><br /></span><br /></div><br /><strong>NB:</strong> The closure here is entered nine times but we can see that it only needs to be entered 5 times because 4 calls are repeated. If we cache the results of the fibonacci calls, the complexity of even a naive implementation such as this will increase linearly, rather than exponentially.<br /><br />Unfortunately, because, in Groovy 1.8, a closure cannot invoke another closure directly, memoizing this closure is not entirely straightforward. The example directly below does not work.<br /><br /><em>RecursiveMemoizationSpec.groovy</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><span style="font-weight: bold; color: rgb(151,44,120);">package</span> <span style="color: rgb(0,0,0);">timezra.groovy.trampoline_memoize</span><br /><br /><span style="font-weight: bold; color: rgb(151,44,120);">class</span> <span style="color: rgb(0,0,0);">RecursiveMemoizationSpec</span> <span style="font-weight: bold; color: rgb(151,44,120);">extends</span> <span style="color: rgb(0,0,0);">spock.lang.Specification</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(151,44,120);">int</span> <span style="color: rgb(102,204,255);">count</span><br /><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(0,0,0);">n</span> <span style="color: rgb(0,0,0);">-></span><br /> <span style="color: rgb(102,204,255);">count</span><span style="color: rgb(0,0,0);">++</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">if</span><span style="color: rgb(0,0,0);">(n</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">0</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(205,50,0);">0</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">else</span> <span style="font-weight: bold; color: rgb(151,44,120);">if</span><span style="color: rgb(0,0,0);">(n</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">1</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(205,50,0);">1</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">else</span> <span style="color: rgb(0,0,0);">fib(n-</span><span style="color: rgb(205,50,0);">1</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">fib(n-</span><span style="color: rgb(205,50,0);">2</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">}.memoize()</span><br /><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(42,0,255);">"calls should be cached"</span><span style="color: rgb(0,0,0);">()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">when:</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">actual</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">10</span><br /><br /> <span style="color: rgb(0,0,0);">then:</span><br /> <span style="color: rgb(0,0,0);">actual</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">55</span><br /> <span style="color: rgb(102,204,255);">count</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">11</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br /><em>The stack trace when a closure calls itself.</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 11pt;"><span style="font-weight: bold; color: rgb(255,0,0);">groovy.lang.MissingMethodException:</span> No signature of method: org.codehaus.groovy.runtime.memoize.Memoize$MemoizeFunction.doCall() is applicable for argument types: (java.lang.Integer) values: [9]<br />Possible solutions: call(), call([Ljava.lang.Object;), call(java.lang.Object), call([Ljava.lang.Object;), findAll(), equals(java.lang.Object)<br /> at timezra.groovy.trampoline_memoize.RecursiveMemoizationSpec.$spock_initializeFields_closure1(RecursiveMemoizationSpec.groovy:11)<br /> at groovy.lang.Closure.call(Closure.java:410)<br /> at groovy.lang.Closure.call(Closure.java:423)<br /> at timezra.groovy.trampoline_memoize.RecursiveMemoizationSpec.calls should be cached(RecursiveMemoizationSpec.groovy:16)<br /></span><br /></div><br /><br />Since methods can invoke memoized closures, the solution is to invoke the call method on the closure.<br /><br /><em>RecursiveMemoizationSpec.groovy</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><span style="font-weight: bold; color: rgb(151,44,120);">class</span> <span style="color: rgb(0,0,0);">RecursiveMemoizationSpec</span> <span style="font-weight: bold; color: rgb(151,44,120);">extends</span> <span style="color: rgb(0,0,0);">spock.lang.Specification</span> <span style="color: rgb(0,0,0);">{</span><br /><span style="color: rgb(0,0,0);">....</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(0,0,0);">n</span> <span style="color: rgb(0,0,0);">-></span><br /> <span style="color: rgb(102,204,255);">count</span><span style="color: rgb(0,0,0);">++</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">if</span><span style="color: rgb(0,0,0);">(n</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">0</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(205,50,0);">0</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">else</span> <span style="font-weight: bold; color: rgb(151,44,120);">if</span><span style="color: rgb(0,0,0);">(n</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">1</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(205,50,0);">1</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">else</span> <span style="color: rgb(0,0,0);">fib.</span><span style="color: rgb(102,204,255);">call</span><span style="color: rgb(0,0,0);">(n-</span><span style="color: rgb(205,50,0);">1</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">fib.</span><span style="color: rgb(102,204,255);">call</span><span style="color: rgb(0,0,0);">(n-</span><span style="color: rgb(205,50,0);">2</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">}.memoize()</span><br /><span style="color: rgb(0,0,0);">....</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><strong>NB:</strong> The un-memoized version enters the closure 177 times, but the memoized version enters just 11.<br /><br /><br /><h4>Trampoline</h4><br />Declarative tail-call optimization is as simple as adding <em>.trampoline()</em> to a closure declaration and ensuring that recursive calls to the closure invoke the trampoline method on the closure instead of the closure itself. Some problems are more clearly solved with recursive solutions, but <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug%5Fid=4726340">without automatic tail-call optimization in the JVM</a>, recursion can quickly lead to an explosion in the size of the call stack. Trampolining is one work-around for this design tradeoff <a href="http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-11.html#%_idx_684">(or defect)</a>.<br />A tail-recursive fibonacci closure:<br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(0,0,0);">n,</span> <span style="color: rgb(0,0,0);">a</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(205,50,0);">0</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">b</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(205,50,0);">1</span> <span style="color: rgb(0,0,0);">-></span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">if</span><span style="color: rgb(0,0,0);">(n</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">0</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">a</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">else</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(0,0,0);">n</span> <span style="color: rgb(0,0,0);">-</span> <span style="color: rgb(205,50,0);">1</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">b,</span> <span style="color: rgb(0,0,0);">a</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">b</span><br /> <span style="color: rgb(0,0,0);">}</span></span><br /></div><br />By tracing the call stack, we can see its linear growth without memoization.<br /><div style="overflow:auto;padding:5px;background-color:silver;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">4</span><br /> <span style="color: rgb(0,0,0);">|</span><br /><span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">3</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(205,50,0);">1</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(205,50,0);">1</span><br /> <span style="color: rgb(0,0,0);">|</span><br /><span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">2</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(205,50,0);">1</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(205,50,0);">2</span><br /> <span style="color: rgb(0,0,0);">|</span><br /><span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">1</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(205,50,0);">2</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(205,50,0);">3</span><br /> <span style="color: rgb(0,0,0);">|</span><br /><span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">0</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(205,50,0);">3</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(205,50,0);">5</span></span><br /></div><br /><br />In order to avoid a <span style="font-weight: bold; color: rgb(255,0,0);">java.lang.StackOverflowError</span> for sufficiently large inputs, the tail-recursive closure must be explicitly <em>trampolined</em>.<br /><em>TrampolineSpec.groovy</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><span style="font-weight: bold; color: rgb(151,44,120);">package</span> <span style="color: rgb(0,0,0);">timezra.groovy.trampoline_memoize</span><br /><br /><span style="font-weight: bold; color: rgb(151,44,120);">class</span> <span style="color: rgb(0,0,0);">TrampolineSpec</span> <span style="font-weight: bold; color: rgb(151,44,120);">extends</span> <span style="color: rgb(0,0,0);">spock.lang.Specification</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(151,44,120);">int</span> <span style="color: rgb(102,204,255);">count</span><br /><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(0,0,0);">n,</span> <span style="color: rgb(0,0,0);">a</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(205,50,0);">0</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">b</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(205,50,0);">1</span> <span style="color: rgb(0,0,0);">-></span><br /> <span style="color: rgb(102,204,255);">count</span><span style="color: rgb(0,0,0);">++</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">if</span><span style="color: rgb(0,0,0);">(n</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">0</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">a</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">else</span> <span style="color: rgb(0,0,0);">fib.trampoline</span> <span style="color: rgb(0,0,0);">n</span> <span style="color: rgb(0,0,0);">-</span> <span style="color: rgb(205,50,0);">1</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">b,</span> <span style="color: rgb(0,0,0);">a</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">b</span><br /> <span style="color: rgb(0,0,0);">}.trampoline()</span><br /><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(42,0,255);">"tail calls chould be optimized"</span><span style="color: rgb(0,0,0);">()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">when:</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">actual</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">1000</span><br /><br /> <span style="color: rgb(0,0,0);">then:</span><br /> <span style="color: rgb(0,0,0);">actual</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">1556111435</span><br /> <span style="color: rgb(102,204,255);">count</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">1001</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br />In this example, the trampolined closure is called 1001 times. If a method in Java were to call itself 1001 times, the stack would be overwhelmed. By trampolining, Groovy turns this recursion into iteration.<br /><br /><h4>Memoizing a Trampolined Closure</h4><br />Suppose we want to cache the results of a computationally expensive tail-recursive closure with no side effects. A trampolined closure that calls itself can easily be memoized in a separate closure declaration.<br /><br /><em>OneTimeTrampolineMemoizationSpec.groovy</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><span style="font-weight: bold; color: rgb(151,44,120);">package</span> <span style="color: rgb(0,0,0);">timezra.groovy.trampoline_memoize</span><br /><br /><span style="font-weight: bold; color: rgb(151,44,120);">class</span> <span style="color: rgb(0,0,0);">OneTimeTrampolineMemoizationSpec</span> <span style="font-weight: bold; color: rgb(151,44,120);">extends</span> <span style="color: rgb(0,0,0);">spock.lang.Specification</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(151,44,120);">int</span> <span style="color: rgb(102,204,255);">count</span><br /><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">fib_aux</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(0,0,0);">n,</span> <span style="color: rgb(0,0,0);">a</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(205,50,0);">0</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">b</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(205,50,0);">1</span> <span style="color: rgb(0,0,0);">-></span><br /> <span style="color: rgb(102,204,255);">count</span><span style="color: rgb(0,0,0);">++</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">if</span><span style="color: rgb(0,0,0);">(n</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">0</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">a</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">else</span> <span style="color: rgb(0,0,0);">fib_aux.trampoline</span> <span style="color: rgb(0,0,0);">n</span> <span style="color: rgb(0,0,0);">-</span> <span style="color: rgb(205,50,0);">1</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">b,</span> <span style="color: rgb(0,0,0);">a</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">b</span><br /> <span style="color: rgb(0,0,0);">}.trampoline()</span><br /><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">fib_aux.memoize()</span><br /><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(42,0,255);">"top-level trampolined calls should be cached"</span><span style="color: rgb(0,0,0);">()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">when:</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">first</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">1000</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">second</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">1000</span><br /><br /> <span style="color: rgb(0,0,0);">then:</span><br /> <span style="color: rgb(102,204,255);">count</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">1001</span><br /> <span style="color: rgb(0,0,0);">first</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">second</span><br /> <span style="color: rgb(0,0,0);">second</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">1556111435</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><strong>NB:</strong> This solution caches the top-level trampolined closure, not the results of the intermediate calls.<br /><br /><h4>Trampolining a Memoized Closure</h4><br />Suppose we want to cache the intermediate results of a trampolined function call. For example, in our trace above, suppose we want to cache the results of <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">4</span> and <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">3</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(205,50,0);">1</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(205,50,0);">1</span> and <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">2</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(205,50,0);">1</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(205,50,0);">2</span> and <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">1</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(205,50,0);">2</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(205,50,0);">3</span> and <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">0</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(205,50,0);">3</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(205,50,0);">5</span></span>.<br />Again, this situation is not straightforward because no closure can call a memoized closure directly, so in this case, the trampolined closure cannot call a memoized version of itself directly. Again, we can use the call function on the memoized closure.<br /><br /><em>FullTrampolineMemoizationSpec.groovy</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><span style="font-weight: bold; color: rgb(151,44,120);">package</span> <span style="color: rgb(0,0,0);">timezra.groovy.trampoline_memoize</span><br /><br /><span style="font-weight: bold; color: rgb(151,44,120);">class</span> <span style="color: rgb(0,0,0);">FullTrampolineMemoizationSpec</span> <span style="font-weight: bold; color: rgb(151,44,120);">extends</span> <span style="color: rgb(0,0,0);">spock.lang.Specification</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(151,44,120);">int</span> <span style="color: rgb(102,204,255);">count</span><br /><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">fib_aux</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(0,0,0);">n,</span> <span style="color: rgb(0,0,0);">a,</span> <span style="color: rgb(0,0,0);">b</span> <span style="color: rgb(0,0,0);">-></span><br /> <span style="color: rgb(102,204,255);">count</span><span style="color: rgb(0,0,0);">++</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">if</span><span style="color: rgb(0,0,0);">(n</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">0</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">a</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">else</span> <span style="color: rgb(0,0,0);">fib.trampoline</span> <span style="color: rgb(0,0,0);">n</span> <span style="color: rgb(0,0,0);">-</span> <span style="color: rgb(205,50,0);">1</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">b,</span> <span style="color: rgb(0,0,0);">a</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">b</span><br /> <span style="color: rgb(0,0,0);">}.memoize()</span><br /><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(0,0,0);">n,</span> <span style="color: rgb(0,0,0);">a</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(205,50,0);">0</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">b</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(205,50,0);">1</span> <span style="color: rgb(0,0,0);">-></span><br /> <span style="color: rgb(0,0,0);">fib_aux.</span><span style="color: rgb(102,204,255);">call</span> <span style="color: rgb(0,0,0);">n,</span> <span style="color: rgb(0,0,0);">a,</span> <span style="color: rgb(0,0,0);">b</span><br /> <span style="color: rgb(0,0,0);">}.trampoline()</span><br /><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(42,0,255);">"all trampolined calls should be cached"</span><span style="color: rgb(0,0,0);">()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">when:</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">first</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">1000</span><br /> <span style="font-weight: bold; color: rgb(151,44,120);">def</span> <span style="color: rgb(0,0,0);">second</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">fib</span> <span style="color: rgb(205,50,0);">500</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(205,50,0);">315178285</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">-</span><span style="color: rgb(205,50,0);">1898383934</span><br /><br /> <span style="color: rgb(0,0,0);">then:</span><br /> <span style="color: rgb(102,204,255);">count</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">1001</span><br /> <span style="color: rgb(0,0,0);">first</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">second</span><br /> <span style="color: rgb(0,0,0);">second</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(205,50,0);">1556111435</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br /><h4>Conclusion</h4><br />Trampolining and memoization are two powerful new features in Groovy 1.8, but the combination of the two is not always straightforward. This tutorial has presented strategies for combining the two and for working around some of the limitations of their combination.Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com0tag:blogger.com,1999:blog-106449775438946661.post-38658150939570683292011-10-19T18:35:00.000-07:002011-11-16T00:35:17.162-08:00Tycho Archetype<h4>Goal</h4><br />The purpose of this blog post is to demonstrate how to generalize <a href="http://timezra.blogspot.com/2011/10/eclipse-plug-ins-program-to-publish.html">a Maven project that suits a specific need</a> into a re-usable archetype, how to publish this archetype to a Maven repository and how to use it as the starting point for similar projects.<br /><br /><h4>tl;dr</h4><br />The <a href="https://github.com/timezra/tycho_new_plugin_project">artifact that is the end result of this tutorial</a> can be used for creating a boilerplate Tycho plug-in project hierarchy with minimal configuration. This generated project will contain a simple Eclipse UI plug-in, an integration-test fragment, a feature that contains the binary plug-in, a feature that contains the source of the plug-in and its test fragment, and an update site for publishing both features.<br /><br /><h4>Generate Archetype From Project</h4><br />Since we are moving from the specific to the general, we begin by cloning the save-actions-extensions project from github.<br /><div style="overflow:auto;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><br /> git clone git://github.com/timezra/save-actions-extensions.git<br /></span><br /></div><br />Since we need only a few of the components from the save-actions-extensions project, we can prune out the extra. We must also rename the <em>features</em>, <em>plugins</em> and <em>update-site</em> directories to match the artifactIds in their respective poms along with the module declarations in the root pom. This directory structure follows the Eclipse convention, but archetype generation will be easier if we make sure that the artifactIds and directory names match. We will also rename the individual plugins and features along with their artifactIds so that there is a consistent name prefix for all projects. Again, this convention will help when generating the archetype.<br /><br /><em>The pruned project</em><br /><div style="overflow:auto;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"> save-actions-extensions<br /> .<br /> |____pom.xml<br /> |____README<br /> | timezra.eclipse.save_actions_extensions.features<br /> | |____pom.xml<br /> | | timezra.eclipse.save_actions_extensions.feature<br /> | | |____build.properties<br /> | | |____feature.properties<br /> | | |____feature.xml<br /> | | |____license.html<br /> | | |____pom.xml<br /> | | timezra.eclipse.save_actions_extensions.source.feature<br /> | | |____build.properties<br /> | | |____feature.properties<br /> | | |____feature.xml<br /> | | |____license.html<br /> | | |____pom.xml<br /> | timezra.eclipse.save_actions_extensions.plugins<br /> | |____pom.xml<br /> | | timezra.eclipse.save_actions_extensions.plugin<br /> | | |____build.properties<br /> | | |____plugin.properties<br /> | | |____pom.xml<br /> | | | META-INF<br /> | | | |____MANIFEST.MF<br /> | | | src<br /> | | | | main<br /> | | | | | java<br /> | | | | | | timezra<br /> | | | | | | | eclipse<br /> | | | | | | | | save_actions_extensions<br /> | | | | | | | | | plugin<br /> | | | | | | | | | |____Activator.java<br /> | | timezra.eclipse.save_actions_extensions.plugin.tests<br /> | | |____build.properties<br /> | | |____plugin.properties<br /> | | |____pom.xml<br /> | | | META-INF<br /> | | | |____MANIFEST.MF<br /> | | | src<br /> | | | | test<br /> | | | | | java<br /> | | | | | | timezra<br /> | | | | | | | eclipse<br /> | | | | | | | | save_actions_extensions<br /> | | | | | | | | | plugin<br /> | | | | | | | | | |____ActivatorTest.java<br /> | timezra.eclipse.save_actions_extensions.update-site<br /> | |____index.html<br /> | |____pom.xml<br /> | |____site.xml<br /> | | web<br /> | | |____site.css<br /> | | |____site.xsl<br /></span><br /></div><br /><br />We are now ready to <a href="http://maven.apache.org/archetype/maven-archetype-plugin/examples/create-multi-module-project.html">generate, install and test the archetype from maven</a>.<br /><br /><strong>NB:</strong> even when specifying filtered extensions, not all files (here <em>README</em>, <em>MANIFEST.MF</em> and <em>site.xsl</em>) are turned into velocity templates, and the hard-coded artifactId references in some files are not all replaced with parameters.<br /><div style="overflow:auto;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"> mvn archetype:create-from-project -Darchetype.filteredExtensions=java,html,xsl,properties,xml,MF<br /> cd target/generated-sources/archetype/<br /> find ./src -type f \( -name "*.MF" -o -name "*.xsl" \) -print0 |xargs -0 perl -pi -e 's/\$/\${symbol_dollar}/g'<br /> find ./src -type f \( -name "*.MF" -o -name "*.xsl" \) -exec perl -pi -e "print qq(#set( \\\$symbol_pound = '#' )\n#set( \\\$symbol_dollar = '\\$' )\n#set( \\\$symbol_escape = '\\\' )\n) if $. == 1" {} \;<br /> find ./src -type f -print0 |xargs -0 perl -pi -e 's/timezra\.eclipse\.save_actions_extensions/\$\{rootArtifactId}/g'<br /> find ./src -type f -print0 |xargs -0 perl -pi -e 's/\$\{groupId}\.save_actions_extensions/\$\{rootArtifactId}/g'<br /> find ./src -name archetype-metadata.xml -exec perl -pi -e 'undef $/; $_=<>; s/\s*\n\s*//g; s~<fileSet encoding="UTF-8"><directory></directory><includes><include>README~<fileSet filtered="true" encoding="UTF-8"><directory></directory><includes><include>README~g;s~<fileSet encoding="UTF-8"><directory>META-INF~<fileSet filtered="true" encoding="UTF-8"><directory>META-INF~g;s~<fileSet encoding="UTF-8"><directory>web</directory><includes><include>\*\*/\*\.xsl</include>~<fileSet filtered="true" encoding="UTF-8"><directory>web</directory><includes><include>**/*.xsl</include></includes></fileSet><fileSet encoding="UTF-8"><directory>web</directory><includes>~g' {} \;<br /> mvn clean install<br /> cd /path/to/tmp/archetype<br /> mvn archetype:generate -DarchetypeCatalog=local<br /> # Choose the new archetype (here local -> timezra.eclipse:timezra.eclipse.save_actions_extensions-archetype)<br /> # Define a groupId (e.g., <em>my.company</em>)<br /> # Define an artifactId (e.g., <em>my.company.do_something</em>)<br /> # Define a version (e.g., <em>1.0.0-SNAPSHOT</em>)<br /> # Define a package (e.g., <em>my.company.do_something.plugin</em>)<br /> cd my.company.do_something<br /> mvn verify<br /></span><br /></div><br /><br />After running this sequence of commands, we should see the eclipse workbench open and successfully run the canary integration test for our test project.<br /><br /><em>The generated project structure</em><br /><div style="overflow:auto;height:250px;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"> my.company.do_something<br /> .<br /> |____pom.xml<br /> |____README<br /> | my.company.do_something.features<br /> | |____pom.xml<br /> | | my.company.do_something.feature<br /> | | |____build.properties<br /> | | |____feature.properties<br /> | | |____feature.xml<br /> | | |____license.html<br /> | | |____pom.xml<br /> | | my.company.do_something.source.feature<br /> | | |____build.properties<br /> | | |____feature.properties<br /> | | |____feature.xml<br /> | | |____license.html<br /> | | |____pom.xml<br /> | my.company.do_something.plugins<br /> | |____pom.xml<br /> | | my.company.do_something.plugin<br /> | | |____build.properties<br /> | | |____plugin.properties<br /> | | |____pom.xml<br /> | | | META-INF<br /> | | | |____MANIFEST.MF<br /> | | | src<br /> | | | | main<br /> | | | | | java<br /> | | | | | | my<br /> | | | | | | | company<br /> | | | | | | | | do_something<br /> | | | | | | | | | plugin<br /> | | | | | | | | | |____Activator.java<br /> | | my.company.do_something.plugin.tests<br /> | | |____build.properties<br /> | | |____plugin.properties<br /> | | |____pom.xml<br /> | | | META-INF<br /> | | | |____MANIFEST.MF<br /> | | | src<br /> | | | | test<br /> | | | | | java<br /> | | | | | | my<br /> | | | | | | | company<br /> | | | | | | | | do_something<br /> | | | | | | | | | plugin<br /> | | | | | | | | | |____ActivatorTest.java<br /> | my.company.do_something.update-site<br /> | |____index.html<br /> | |____pom.xml<br /> | |____site.xml<br /> | | web<br /> | | |____site.css<br /> | | |____site.xsl<br /></span><br /></div><br /><br /><h4>Dynamic Directories</h4><br />On closer comparison of the directory tree from the original project and the generated project, you might wonder how Maven knows to name folders based on the artifactIds.<br />If we look at the generated archetype, we will see a parameterized directory structure.<br /><br /><em>Parameterized directories are in red</em><br /><div style="overflow:auto;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"> archetype<br /> .<br /> |____pom.xml<br /> | src<br /> | | main<br /> | | | resources<br /> | | | | archetype-resources<br /> | | | | |____pom.xml<br /> | | | | |____README<br /><span style="color: red; font-weight: bold"> | | | | | __rootArtifactId__.features</span><br /> | | | | | |____pom.xml<br /><span style="color: red; font-weight: bold"> | | | | | | __rootArtifactId__.feature</span><br /> | | | | | | |____build.properties<br /> | | | | | | |____feature.properties<br /> | | | | | | |____feature.xml<br /> | | | | | | |____license.html<br /> | | | | | | |____pom.xml<br /><span style="color: red; font-weight: bold"> | | | | | | __rootArtifactId__.source.feature</span><br /> | | | | | | |____build.properties<br /> | | | | | | |____feature.properties<br /> | | | | | | |____feature.xml<br /> | | | | | | |____license.html<br /> | | | | | | |____pom.xml<br /><span style="color: red; font-weight: bold"> | | | | | __rootArtifactId__.plugins</span><br /> | | | | | |____pom.xml<br /><span style="color: red; font-weight: bold"> | | | | | | __rootArtifactId__.plugin</span><br /> | | | | | | |____build.properties<br /> | | | | | | |____plugin.properties<br /> | | | | | | |____pom.xml<br /> | | | | | | | META-INF<br /> | | | | | | | |____MANIFEST.MF<br /> | | | | | | | src<br /> | | | | | | | | main<br /> | | | | | | | | | java<br /> | | | | | | | | | |____Activator.java<br /><span style="color: red; font-weight: bold"> | | | | | | __rootArtifactId__.plugin.tests</span><br /> | | | | | | |____build.properties<br /> | | | | | | |____plugin.properties<br /> | | | | | | |____pom.xml<br /> | | | | | | | META-INF<br /> | | | | | | | |____MANIFEST.MF<br /> | | | | | | | src<br /> | | | | | | | | test<br /> | | | | | | | | | java<br /> | | | | | | | | | |____ActivatorTest.java<br /><span style="color: red; font-weight: bold"> | | | | | __rootArtifactId__.update-site</span><br /> | | | | | |____index.html<br /> | | | | | |____pom.xml<br /> | | | | | |____site.xml<br /> | | | | | | web<br /> | | | | | | |____site.css<br /> | | | | | | |____site.xsl<br /> | | | | META-INF<br /> | | | | | maven<br /> | | | | | |____archetype-metadata.xml<br /> | | test<br /> | | | resources<br /> | | | | projects<br /> | | | | | basic<br /> | | | | | |____archetype.properties<br /> | | | | | |____goal.txt<br /></span><br /></div><br /><br />You might also notice that the <em>Activator.java</em> and <em>ActivatorTest.java</em> are contained in the root of their <em>src/main/java</em> and <em>src/test/java</em> folders, respectively, in the archetype resources; however, in the generated project, the files are in the proper subdirectories with corresponding package declarations. In the generated <em>archetype-metadata.xml</em>, the contents of these source directories are <em>filtered</em> and <em>packaged</em>.<br /><br /><em>src/main/resources/META-INF/maven/archetype-metadata.xml</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">archetype-descriptor</span> ....<span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">modules</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">module</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"${rootArtifactId}.plugins"</span> ....<span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">modules</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">module</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"${rootArtifactId}.plugin"</span> ....<span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">fileSets</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">fileSet</span> <span style="color: rgb(127,0,127); font-weight: bold; font-size: 15pt;">filtered</span>=<span style="font-style: italic; color: rgb(42,0,255);">"true"</span> <span style="color: rgb(127,0,127); font-weight: bold; font-size: 15pt;">packaged</span>=<span style="font-style: italic; color: rgb(42,0,255);">"true"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">directory</span><span style="color: rgb(0,128,128);">></span>src/main/java<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">directory</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">includes</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">include</span><span style="color: rgb(0,128,128);">></span>**/*.java<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">include</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">includes</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">fileSet</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">fileSets</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">module</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">module</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"${rootArtifactId}.plugin.tests"</span> ....<span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">fileSets</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">fileSet</span> <span style="color: rgb(127,0,127); font-weight: bold; font-size: 15pt;">filtered</span>=<span style="font-style: italic; color: rgb(42,0,255);">"true"</span> <span style="color: rgb(127,0,127); font-weight: bold; font-size: 15pt;">packaged</span>=<span style="font-style: italic; color: rgb(42,0,255);">"true"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">directory</span><span style="color: rgb(0,128,128);">></span>src/test/java<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">directory</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">includes</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">include</span><span style="color: rgb(0,128,128);">></span>**/*.java<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">include</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">includes</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">fileSet</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">fileSets</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">module</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">modules</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">module</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">modules</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">archetype-descriptor</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><br /><h4>Testing</h4><br />After customizing our resources and adding any additional required properties, we can integration-test the archetype using a golden template project contained in the <em>src/test/projects/basic/reference</em> directory. For this example, if the generated <em>my.company.do_something</em> project above exactly meets our needs, then we can simply copy the entire contents of this directory to the <em>src/test/projects/basic/reference</em> folder and update the <em>archetype.properties</em> to match the properties we used for project generation.<br /><br /><em>src/test/resources/projects/basic/archetype.properties</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><span style="color: rgb(0,0,0);">groupId</span><span style="color: rgb(0,0,0);">=</span><span style="color: rgb(42,0,255);">my.company</span><br /><span style="color: rgb(0,0,0);">artifactId</span><span style="color: rgb(0,0,0);">=</span><span style="color: rgb(42,0,255);">my.company.do_something</span><br /><span style="color: rgb(0,0,0);">version</span><span style="color: rgb(0,0,0);">=</span><span style="color: rgb(42,0,255);">1.0.0-SNAPSHOT</span><br /><span style="color: rgb(0,0,0);">package</span><span style="color: rgb(0,0,0);">=</span><span style="color: rgb(42,0,255);">my.company.do_something.plugin</span><br /></span><br /></div><br /><br />During the integration-test phase, Maven will generate a sample project from the archetype with these properties and will compare the results with the golden template.<br /><div style="overflow:auto;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><br /> mvn verify<br /></span><br /></div><br /><strong>NB:</strong> use of this type of golden template can be very brittle, and any changes made to files in the <em>src/main/resources/archetype-resources</em> directory must be reflected by equivalent changes in the <em>src/test/resources/projects/basic/reference</em> directory.<br /><br /><h4>Publish to a Maven Repository</h4><br />Now that our Maven archetype is tested and ready for publication, we can publish it, either to <a href="http://archiva.apache.org/docs/1.0.1/userguide/deploy.html">an</a> <a href="http://www.sonatype.com/books/nexus-book/reference/staging-sect-update-pom.html">internal</a> <a href="http://wiki.jfrog.org/confluence/display/RTF/Configuring+Deployment">repository</a>, to <a href="https://docs.sonatype.org/display/Repository/Sonatype+OSS+Maven+Repository+Usage+Guide">the sonatype repository</a>, which will synch our artifact with Maven central, or to a private repository, which in our case can simply be <a href="http://cemerick.com/2010/08/24/hosting-maven-repos-on-github/">github pages</a>.<br />We want to partition our repository into <em>snapshots</em> and <em>releases</em>, and we will need archetype catalogs in a subfolder of each.<br />We can deploy our archetype to a folder that contains the gh-pages branch of a github project called <em>maven</em>, which will contain all our published maven artifacts.<br /><br /><div style="overflow:auto;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><br /> mvn -DaltDeploymentRepository=snapshot-repo::default::file:/path/to/git_maven_repository/snapshots clean deploy<br /></span><br /></div><br /><br />Since we have installed the archetype, we already have a <em>~/.m2/archetype-catalog.xml</em> file.<br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">archetype-catalog</span><br /> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/plugins/maven-archetype-plugin/archetype-catalog/1.0.0 http://maven.apache.org/xsd/archetype-catalog-1.0.0.xsd"</span><br /> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/plugins/maven-archetype-plugin/archetype-catalog/1.0.0"</span> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">archetypes</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">archetype</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>timezra.eclipse<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>timezra.eclipse.save_actions_extensions-archetype<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.0.0-SNAPSHOT<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">description</span><span style="color: rgb(0,128,128);">></span>Parent project for the timezra.eclipse.save_actions_extensions project set<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">description</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">archetype</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">archetypes</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">archetype-catalog</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br /><em>The Maven repository</em><br /><div style="overflow:auto;height:250px;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"> github_maven_repository<br /> .<br /> | releases<br /> | snapshots<br /> | | archetypes<br /> | | |____archetype-catalog.xml<br /> | | timezra<br /> | | | eclipse<br /> | | | | timezra.eclipse.save_actions_extensions-archetype<br /> | | | | |____maven-metadata.xml<br /> | | | | |____maven-metadata.xml.md5<br /> | | | | |____maven-metadata.xml.sha1<br /> | | | | | 1.0.0-SNAPSHOT<br /> | | | | | |____maven-metadata.xml<br /> | | | | | |____maven-metadata.xml.md5<br /> | | | | | |____maven-metadata.xml.sha1<br /> | | | | | |____timezra.eclipse.save_actions_extensions-archetype-1.0.0-20111020.005931-1.jar<br /> | | | | | |____timezra.eclipse.save_actions_extensions-archetype-1.0.0-20111020.005931-1.jar.md5<br /> | | | | | |____timezra.eclipse.save_actions_extensions-archetype-1.0.0-20111020.005931-1.jar.sha1<br /> | | | | | |____timezra.eclipse.save_actions_extensions-archetype-1.0.0-20111020.005931-1.pom<br /> | | | | | |____timezra.eclipse.save_actions_extensions-archetype-1.0.0-20111020.005931-1.pom.md5<br /> | | | | | |____timezra.eclipse.save_actions_extensions-archetype-1.0.0-20111020.005931-1.pom.sha1<br /></span><br /></div><br /><br /><h4>Use the Archetype From the Repository</h4><br /><br />After our artifacts have been deployed to a Maven repository, we can generate a project from the deployed archetype in a way similar to how we generated the project from the archetype installed locally above.<br /><br /><em>Generating from an artifact in a gh-pages repository</em><br /><div style="overflow:auto;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><br /> mvn archetype:generate -DarchetypeCatalog=http://your_github_username.github.com/maven/snapshots/archetypes<br /></span><br /></div><br /><br /><h4>Conclusion</h4><br />This tutorial is a continuation of a <a href="http://timezra.blogspot.com/2011/10/eclipse-plug-ins-program-to-publish.html">previous post</a>, in which we created a set of Tycho-enabled Eclipse projects. The archetype we created from this set of projects abstracts the boilerplate and conventions into a re-usable component that will make setting up similar projects even faster in the future.<br />The end result of this effort is the <a href="https://github.com/timezra/tycho_new_plugin_project">tycho_new_plugin_project</a>.Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com0tag:blogger.com,1999:blog-106449775438946661.post-28153776770086585562011-10-12T00:18:00.000-07:002011-10-17T16:55:35.731-07:00Eclipse Plug-ins: Program to Publish<h4>Goal</h4><br />The purpose of this blog entry is to demonstrate one workflow for taking an idea for an Eclipse plug-in from concept to product downloadable from the Eclipse marketplace.<br /><br /><h4>tl;dr</h4><br />If you want to look right away at working code for a simple Eclipse plug-in, feature, update site and their <a href="http://www.eclipse.org/tycho/">Tycho</a> configurations, a <a href="https://github.com/timezra/save-actions-extensions">sample project</a> based on this tutorial is available. The plug-in can also be installed in Eclipse through the <a href="http://marketplace.eclipse.org">Marketplace</a> (search for "save actions") or directly from an <a href="http://timezra.github.com/save-actions-extensions/">update site</a>. In addition, the conventions for project setup contained in this tutorial have been extracted into <a href="https://github.com/timezra/tycho_new_plugin_project">a Maven archetype</a>. Since this blog entry does not provide an in-depth introduction to the nuances of configuring and writing Eclipse plug-ins, having the project source as a reference, either locally or in a web browser, will be helpful for following the examples.<br /><br /><h4>The Idea</h4><br />Suppose we are starting a new project on an existing codebase and, as part of our Working Agreement, the team has decided to automate certain coding standards with Eclipse Java editor save actions. It would be convenient to bring all the existing code up to our standards before development even begins. Currently, formatting and import organization can be performed in bulk from the source submenu in the workbench. Eclipse users can also apply clean-up conventions from this submenu. Unfortunately, even though the clean-up and save participants have similar configurations, there is a disconnect between the two.<br />Exposing save actions for the bulk processing of Java/Groovy files through this source submenu is a simple enough feature to add to Eclipse and should provide the opportunity to experience one full cycle of Eclipse plug-in development, from the creation of a simple plug-in and its integration tests, to the addition of a feature to contain the plug-in, to the packaging of an update site, to the distribution of the product through the <a href="http://marketplace.eclipse.org">Eclipse Marketplace</a>.<br /><br /><h4>The Plug-in</h4><br />We will begin by creating a new plug-in project named <em>timezra.eclipse.apply_save_actions</em> in our Eclipse workspace. Since we will eventually generate a Tycho configuration in order to automate the compilation, testing and packaging of our product, we will modify a few of the default settings for the plug-in. Our plug-in and fragment projects will be contained in a <em>plugins</em> subdirectory, here <em>/path/to/workspace/plugins/timezra.eclipse.apply_save_actions</em>. Our source folder will be <em>src/main/java</em> and output folder will be <em>target/classes</em> to follow the Maven convention.<br /><br /><img alt="The New Plug-in Project wizard with Maven-inspired configurations" src="http://farm7.static.flickr.com/6110/6236573817_b280ed1379_z.jpg" /><br /><br />We can either use the New Plug-in Project Wizard <em>Hello, World Command Template</em> or we can contribute a command to a menu with manual configuration. There are already quite a <a href="http://my.safaribooksonline.com/book/software-engineering-and-development/ide/9780321574435/commands-and-actions/ch06lev1sec1">few</a> <a href="http://help.eclipse.org/indigo/index.jsp?topic=/org.eclipse.platform.doc.isv/guide/workbench_cmd_handlers.htm">resources</a> <a href="http://www.eclipse-tips.com/tutorials/1-actions-vs-commands">for</a> <a href="http://wiki.eclipse.org/Platform_Command_Framework">contributing</a> <a href="http://www.vogella.de/articles/EclipseCommands/article.html">commands</a> through an extension point, so you can get more insight into specific configuration settings there.<br />For this example, the configuration is boilerplate. The internals of the ApplySaveActions command handler are somewhat interesting. There may be a more direct way to invoke the save participant, but this method works on both un-opened files and source buffers modified in memory for Java and Groovy, so in the interest of <a href="http://www.xprogramming.com/Practices/PracSimplest.html">DTSTTCPW</a>, we can use this simple implementation until it is no longer sufficient.<br /><br /><em>plugins/timezra.eclipse.apply_save_actions/src/main/java/timezra/eclipse/apply_save_actions/handlers/ApplySaveActions.java</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span><span style="color: rgb(0,0,0);"> timezra.eclipse.apply_save_actions.handlers;<br /><br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">static</span><span style="color: rgb(0,0,0);"> java.util.Arrays.asList;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> java.lang.reflect.InvocationTargetException;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> java.util.ArrayList;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> java.util.Collection;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.commands.AbstractHandler;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.commands.ExecutionEvent;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.commands.ExecutionException;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.resources.IFile;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.resources.IWorkspace;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.resources.ResourcesPlugin;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.runtime.CoreException;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.runtime.IAdapterManager;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.runtime.IProgressMonitor;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.runtime.OperationCanceledException;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.runtime.Platform;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.jdt.core.ICompilationUnit;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.jdt.core.IJavaElement;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.jdt.core.IJavaProject;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.jdt.core.IPackageFragment;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.jdt.core.IPackageFragmentRoot;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.jdt.core.JavaModelException;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.jface.operation.IRunnableWithProgress;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.jface.viewers.ISelection;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.jface.viewers.IStructuredSelection;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.ui.IWorkbench;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.ui.PlatformUI;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.ui.actions.WorkspaceModifyOperation;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.ui.handlers.HandlerUtil;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.ui.part.FileEditorInput;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.ui.texteditor.IDocumentProvider;<br /><br /></span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);"> ApplySaveActions </span><span style="font-weight: bold; color: rgb(127,0,85);">extends</span><span style="color: rgb(0,0,0);"> AbstractHandler {<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IAdapterManager adapterManager;<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IWorkspace workspace;<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IWorkbench workbench;<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> ApplySaveActions() {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">(Platform.getAdapterManager(), ResourcesPlugin.getWorkspace(), PlatformUI.getWorkbench());<br /> }<br /><br /> ApplySaveActions(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IAdapterManager adapterManager, </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IWorkspace workspace, </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IWorkbench workbench) {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.adapterManager = adapterManager;<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.workspace = workspace;<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.workbench = workbench;<br /> }<br /><br /> @Override<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> Object execute(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> ExecutionEvent event) </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> ExecutionException {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> ISelection currentSelection = HandlerUtil.getCurrentSelectionChecked(event);<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">if</span><span style="color: rgb(0,0,0);"> (currentSelection </span><span style="font-weight: bold; color: rgb(127,0,85);">instanceof</span><span style="color: rgb(0,0,0);"> IStructuredSelection) {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IStructuredSelection selections = (IStructuredSelection) currentSelection;<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">try</span><span style="color: rgb(0,0,0);"> {<br /> applyTo(selections);<br /> } </span><span style="font-weight: bold; color: rgb(127,0,85);">catch</span><span style="color: rgb(0,0,0);"> (</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> JavaModelException e) {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">throw</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> ExecutionException(Messages.APPLY_SAVE_ACTIONS_UNEXPECTED_ERROR, e);<br /> } </span><span style="font-weight: bold; color: rgb(127,0,85);">catch</span><span style="color: rgb(0,0,0);"> (</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> InvocationTargetException e) {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">throw</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> ExecutionException(Messages.APPLY_SAVE_ACTIONS_UNEXPECTED_ERROR, e.getTargetException());<br /> }<br /> }<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">return</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">;<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> applyTo(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IStructuredSelection selections) </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> JavaModelException, InvocationTargetException {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">for</span><span style="color: rgb(0,0,0);"> (</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> Object o : selections.toList()) {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IJavaProject javaProject = getAdapter(o, IJavaProject.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">);<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">if</span><span style="color: rgb(0,0,0);"> (javaProject != </span><span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">) {<br /> applyTo(javaProject.getPackageFragments());<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">continue</span><span style="color: rgb(0,0,0);">;<br /> }<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IPackageFragmentRoot packageFragmentRoot = getAdapter(o, IPackageFragmentRoot.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">);<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">if</span><span style="color: rgb(0,0,0);"> (packageFragmentRoot != </span><span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">) {<br /> applyTo(packageFragmentRoot);<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">continue</span><span style="color: rgb(0,0,0);">;<br /> }<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IPackageFragment packageFragment = getAdapter(o, IPackageFragment.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">);<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">if</span><span style="color: rgb(0,0,0);"> (packageFragment != </span><span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">) {<br /> applyTo(packageFragment);<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">continue</span><span style="color: rgb(0,0,0);">;<br /> }<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> ICompilationUnit compilationUnit = getAdapter(o, ICompilationUnit.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">);<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">if</span><span style="color: rgb(0,0,0);"> (compilationUnit != </span><span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">) {<br /> applyTo(compilationUnit);<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">continue</span><span style="color: rgb(0,0,0);">;<br /> }<br /> }<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> applyTo(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IPackageFragmentRoot packageFragmentRoot) </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> JavaModelException,<br /> InvocationTargetException {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IJavaElement[] children = packageFragmentRoot.getChildren();<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IPackageFragment[] fragments = </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> IPackageFragment[children.length];<br /> System.arraycopy(children, 0, fragments, 0, children.length);<br /> applyTo(fragments);<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> applyTo(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IPackageFragment... packageFragments) </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> JavaModelException,<br /> InvocationTargetException {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> Collection<ICompilationUnit> compilationUnits = </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> ArrayList<ICompilationUnit>();<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">for</span><span style="color: rgb(0,0,0);"> (</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IPackageFragment f : packageFragments) {<br /> compilationUnits.addAll(asList(f.getCompilationUnits()));<br /> }<br /> applyTo(compilationUnits.toArray(</span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> ICompilationUnit[compilationUnits.size()]));<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> applyTo(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> ICompilationUnit... compilationUnits) </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> InvocationTargetException {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IRunnableWithProgress delegate = </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> ApplySaveActionsOperation(compilationUnits);<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">try</span><span style="color: rgb(0,0,0);"> {<br /> workbench.getProgressService().run(</span><span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">, </span><span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">, delegate);<br /> } </span><span style="font-weight: bold; color: rgb(127,0,85);">catch</span><span style="color: rgb(0,0,0);"> (</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> InterruptedException e) {<br /> </span><span style="color: rgb(63,127,95);">// cancellation is fine<br /></span><span style="color: rgb(0,0,0);"> }<br /> }<br /><br /> @SuppressWarnings(</span><span style="color: rgb(42,0,255);">"restriction"</span><span style="color: rgb(0,0,0);">)<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> IDocumentProvider createDocumentProvider() {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">return</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> org.eclipse.jdt.internal.ui.javaeditor.CompilationUnitDocumentProvider();<br /> }<br /><br /> @SuppressWarnings(</span><span style="color: rgb(42,0,255);">"unchecked"</span><span style="color: rgb(0,0,0);">)<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> <T> T getAdapter(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> Object o, </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> Class<T> c) {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">return</span><span style="color: rgb(0,0,0);"> (T) adapterManager.getAdapter(o, c);<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);"> ApplySaveActionsOperation </span><span style="font-weight: bold; color: rgb(127,0,85);">extends</span><span style="color: rgb(0,0,0);"> WorkspaceModifyOperation {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> ICompilationUnit[] compilationUnits;<br /><br /> ApplySaveActionsOperation(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> ICompilationUnit... compilationUnits) {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.compilationUnits = compilationUnits;<br /> }<br /><br /> @Override<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> execute(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IProgressMonitor pm) </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> CoreException {<br /> pm.beginTask(Messages.APPLY_SAVE_ACTIONS_BEGIN_TASK, compilationUnits.length);<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">try</span><span style="color: rgb(0,0,0);"> {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">for</span><span style="color: rgb(0,0,0);"> (</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> ICompilationUnit unit : compilationUnits) {<br /> applyTo(workspace.getRoot().getFile(unit.getPath()), pm);<br /> }<br /> } </span><span style="font-weight: bold; color: rgb(127,0,85);">finally</span><span style="color: rgb(0,0,0);"> {<br /> pm.done();<br /> }<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> applyTo(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IFile f, </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IProgressMonitor pm) </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> CoreException {<br /> report(f.getName(), pm);<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IDocumentProvider provider = createDocumentProvider();<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> FileEditorInput editorInput = </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> FileEditorInput(f);<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">try</span><span style="color: rgb(0,0,0);"> {<br /> provider.connect(editorInput);<br /> provider.aboutToChange(editorInput);<br /> provider.saveDocument(pm, editorInput, provider.getDocument(editorInput), </span><span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">);<br /> } </span><span style="font-weight: bold; color: rgb(127,0,85);">finally</span><span style="color: rgb(0,0,0);"> {<br /> provider.changed(editorInput);<br /> provider.disconnect(editorInput);<br /> }<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> report(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> String task, </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IProgressMonitor pm) {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">if</span><span style="color: rgb(0,0,0);"> (pm.isCanceled()) {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">throw</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> OperationCanceledException();<br /> }<br /> pm.setTaskName(task);<br /> pm.worked(1);<br /> }<br /> }<br />}<br /></span></span><br /></div><br /><br /><h4>The Test Fragment</h4><br />We will similarly create a new integration test fragment alongside this plug-in, overriding the default configuration to store the fragment into the <em>plugins</em> subdirectory and to use Maven conventions for the source and output directories.<br /><br /><img alt="The New Fragment Project wizard with Maven-inspired configurations" src="http://farm7.static.flickr.com/6211/6236573901_762ff9c69f_z.jpg" /><br /><br />There are <a href="http://www.modumind.com/2007/06/20/unit-testing-plug-ins-with-fragments/">various approaches</a> for testing Eclipse plug-ins, but the fragment approach has been <a href="http://wiki.eclipse.org/Tycho/Packaging_Types#eclipse-test-plugin">embraced by the Tycho community</a>, so we will use it here.<br />Again, the project configuration can be boilerplate for now. Of particular interest is the handler test case.<br /><br /><em>plugins/timezra.eclipse.apply_save_actions.tests/src/test/java/timezra/eclipse/apply_save_actions/handlers/ApplySaveActions.java</em><br /><div style="overflow:auto;height:1200x;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span><span style="color: rgb(0,0,0);"> timezra.eclipse.apply_save_actions.handlers;<br /><br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">static</span><span style="color: rgb(0,0,0);"> org.junit.Assert.assertEquals;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">static</span><span style="color: rgb(0,0,0);"> org.junit.Assert.assertNull;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> java.io.ByteArrayInputStream;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> java.io.IOException;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> java.util.ArrayList;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> java.util.Collections;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> java.util.HashMap;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> java.util.List;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> java.util.Map;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> java.util.Scanner;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.commands.ExecutionEvent;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.commands.ExecutionException;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.expressions.EvaluationContext;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.resources.IContainer;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.resources.IFile;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.resources.IFolder;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.resources.IProject;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.resources.IResource;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.resources.IWorkspaceRoot;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.resources.ResourcesPlugin;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.runtime.CoreException;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.runtime.IProgressMonitor;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.runtime.NullProgressMonitor;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.runtime.Path;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.runtime.SubProgressMonitor;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.core.runtime.preferences.InstanceScope;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.jdt.core.IClasspathEntry;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.jdt.core.IJavaProject;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.jdt.core.JavaCore;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.jdt.launching.JavaRuntime;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.jdt.ui.JavaUI;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.jdt.ui.cleanup.CleanUpOptions;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.jface.text.TextSelection;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.jface.viewers.StructuredSelection;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.eclipse.ui.ISources;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.junit.After;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.junit.Before;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.junit.Rule;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.junit.Test;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.junit.rules.MethodRule;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> timezra.eclipse.apply_save_actions.Constants;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> timezra.eclipse.apply_save_actions.tests.ModifiesSaveActionsPreferences;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> timezra.eclipse.apply_save_actions.tests.ModifiesSaveActionsPreferencesRule;<br /><br /></span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);"> ApplySaveActionsPluginTest {<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">static</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> String SOURCE_FOLDER = </span><span style="color: rgb(42,0,255);">"src/test/java"</span><span style="color: rgb(0,0,0);">;<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">static</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> String EOL = System.getProperty(</span><span style="color: rgb(42,0,255);">"line.separator"</span><span style="color: rgb(0,0,0);">);<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">static</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IProgressMonitor NULL_PROGRESS_MONITOR = </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> NullProgressMonitor();<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">static</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> String TEST_CLASS = </span><span style="color: rgb(42,0,255);">"TestClass"</span><span style="color: rgb(0,0,0);">;<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">static</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> String TEST_PACKAGE = </span><span style="color: rgb(42,0,255);">"timezra.eclipse.apply_save_actions"</span><span style="color: rgb(0,0,0);">;<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">static</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> String TEST_CLASS_BEFORE_SAVE_ACTIONS = </span><span style="color: rgb(42,0,255);">"package "</span><span style="color: rgb(0,0,0);"> + TEST_PACKAGE<br /> + </span><span style="color: rgb(42,0,255);">";import java.util.*;class "</span><span style="color: rgb(0,0,0);"> + TEST_CLASS + </span><span style="color: rgb(42,0,255);">"{private List<"</span><span style="color: rgb(0,0,0);"> + TEST_CLASS + </span><span style="color: rgb(42,0,255);">"> l;"</span><span style="color: rgb(0,0,0);"> + TEST_CLASS<br /> + </span><span style="color: rgb(42,0,255);">"(List<"</span><span style="color: rgb(0,0,0);"> + TEST_CLASS + </span><span style="color: rgb(42,0,255);">"> l){this.l=l;}}"</span><span style="color: rgb(0,0,0);">;<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">static</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> String TEST_CLASS_AFTER_SAVE_ACTIONS = </span><span style="color: rgb(42,0,255);">"package "</span><span style="color: rgb(0,0,0);"> + TEST_PACKAGE + </span><span style="color: rgb(42,0,255);">";"</span><span style="color: rgb(0,0,0);"> + EOL + </span><span style="color: rgb(63,127,95);">//<br /></span><span style="color: rgb(0,0,0);"> EOL + </span><span style="color: rgb(63,127,95);">//<br /></span><span style="color: rgb(0,0,0);"> </span><span style="color: rgb(42,0,255);">"import java.util.List;"</span><span style="color: rgb(0,0,0);"> + EOL + </span><span style="color: rgb(63,127,95);">//<br /></span><span style="color: rgb(0,0,0);"> EOL + </span><span style="color: rgb(63,127,95);">//<br /></span><span style="color: rgb(0,0,0);"> </span><span style="color: rgb(42,0,255);">"class "</span><span style="color: rgb(0,0,0);"> + TEST_CLASS + </span><span style="color: rgb(42,0,255);">" {"</span><span style="color: rgb(0,0,0);"> + EOL + </span><span style="color: rgb(63,127,95);">//<br /></span><span style="color: rgb(0,0,0);"> </span><span style="color: rgb(42,0,255);">" private final List<"</span><span style="color: rgb(0,0,0);"> + TEST_CLASS + </span><span style="color: rgb(42,0,255);">"> l;"</span><span style="color: rgb(0,0,0);"> + EOL + </span><span style="color: rgb(63,127,95);">//<br /></span><span style="color: rgb(0,0,0);"> EOL + </span><span style="color: rgb(63,127,95);">//<br /></span><span style="color: rgb(0,0,0);"> </span><span style="color: rgb(42,0,255);">" "</span><span style="color: rgb(0,0,0);"> + TEST_CLASS + </span><span style="color: rgb(42,0,255);">"(List<"</span><span style="color: rgb(0,0,0);"> + TEST_CLASS + </span><span style="color: rgb(42,0,255);">"> l) {"</span><span style="color: rgb(0,0,0);"> + EOL + </span><span style="color: rgb(63,127,95);">//<br /></span><span style="color: rgb(0,0,0);"> </span><span style="color: rgb(42,0,255);">" this.l = l;"</span><span style="color: rgb(0,0,0);"> + EOL + </span><span style="color: rgb(63,127,95);">//<br /></span><span style="color: rgb(0,0,0);"> </span><span style="color: rgb(42,0,255);">" }"</span><span style="color: rgb(0,0,0);"> + EOL + </span><span style="color: rgb(63,127,95);">//<br /></span><span style="color: rgb(0,0,0);"> </span><span style="color: rgb(42,0,255);">"}"</span><span style="color: rgb(0,0,0);">;<br /><br /> @Rule<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> MethodRule rule = </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> ModifiesSaveActionsPreferencesRule();<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> IProject aJavaProject;<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> IFolder aJavaPackage;<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> IFile aJavaFile;<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> IFolder aJavaSourceFolder;<br /><br /> @Before<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> setUp() </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> CoreException {<br /> aJavaProject = createAJavaProject(</span><span style="color: rgb(42,0,255);">"a_java_project"</span><span style="color: rgb(0,0,0);">);<br /> aJavaSourceFolder = createASourceFolder(SOURCE_FOLDER);<br /> aJavaPackage = createAPackage(aJavaSourceFolder, TEST_PACKAGE.replaceAll(</span><span style="color: rgb(42,0,255);">"\\."</span><span style="color: rgb(0,0,0);">, </span><span style="color: rgb(42,0,255);">"/"</span><span style="color: rgb(0,0,0);">));<br /> aJavaFile = createAJavaFile(aJavaPackage, TEST_CLASS + </span><span style="color: rgb(42,0,255);">".java"</span><span style="color: rgb(0,0,0);">);<br /> }<br /><br /> @After<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> tearDown() </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> CoreException {<br /> aJavaProject.delete(</span><span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">, NULL_PROGRESS_MONITOR);<br /> }<br /><br /> @Test<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> theCurrentSelectionMustBeStructured() </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> ExecutionException {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> ApplySaveActions command = </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> ApplySaveActions();<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> EvaluationContext context = </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> EvaluationContext(</span><span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">, </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> Object());<br /> context.addVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME, </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> TextSelection(0, 100));<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> ExecutionEvent event = </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> ExecutionEvent(</span><span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">, Collections.emptyMap(), </span><span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">, context);<br /> assertNull(command.execute(event));<br /> }<br /><br /> @Test<br /> @ModifiesSaveActionsPreferences<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> aJavaFileCanBeReformatted() </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> ExecutionException, CoreException, IOException {<br /> enableJavaSaveActions();<br /><br /> applySaveActions(JavaCore.create(aJavaFile));<br /><br /> verifyThatSaveActionsHaveBeenApplied(aJavaFile);<br /> }<br /><br /> @Test<br /> @ModifiesSaveActionsPreferences<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> aJavaPackageCanBeReformatted() </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> ExecutionException, CoreException, IOException {<br /> enableJavaSaveActions();<br /><br /> applySaveActions(JavaCore.create(aJavaPackage));<br /><br /> verifyThatSaveActionsHaveBeenApplied(aJavaFile);<br /> }<br /><br /> @Test<br /> @ModifiesSaveActionsPreferences<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> aJavaSourceFolderCanBeReformatted() </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> ExecutionException, CoreException, IOException {<br /> enableJavaSaveActions();<br /><br /> applySaveActions(JavaCore.create(aJavaSourceFolder));<br /><br /> verifyThatSaveActionsHaveBeenApplied(aJavaFile);<br /> }<br /><br /> @Test<br /> @ModifiesSaveActionsPreferences<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> aJavaProjectCanBeReformatted() </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> ExecutionException, CoreException {<br /> enableJavaSaveActions();<br /><br /> applySaveActions(JavaCore.create(aJavaProject));<br /><br /> verifyThatSaveActionsHaveBeenApplied(aJavaFile);<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> applySaveActions(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> Object selection) </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> ExecutionException {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> ApplySaveActions command = </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> ApplySaveActions();<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> EvaluationContext context = </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> EvaluationContext(</span><span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">, </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> Object());<br /> context.addVariable(ISources.ACTIVE_CURRENT_SELECTION_NAME, </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> StructuredSelection(selection));<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> ExecutionEvent event = </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> ExecutionEvent(</span><span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">, Collections.emptyMap(), </span><span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">, context);<br /> command.execute(event);<br /> }<br /><br /> </span><span style="color: rgb(63,127,95);">// contains a beaut that turns a stream into a String without using IoUtils:<br /></span><span style="color: rgb(0,0,0);"> </span><span style="color: rgb(63,127,95);">// http://stackoverflow.com/questions/309424/in-java-how-do-a-read-convert-an-inputstream-in-to-a-string<br /></span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> verifyThatSaveActionsHaveBeenApplied(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IFile aJavaFile) </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> CoreException {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> String actualContents;<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> Scanner scanner = </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> Scanner(aJavaFile.getContents());<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">try</span><span style="color: rgb(0,0,0);"> {<br /> actualContents = scanner.useDelimiter(</span><span style="color: rgb(42,0,255);">"\\A"</span><span style="color: rgb(0,0,0);">).next();<br /> } </span><span style="font-weight: bold; color: rgb(127,0,85);">finally</span><span style="color: rgb(0,0,0);"> {<br /> scanner.close();<br /> }<br /> assertEquals(TEST_CLASS_AFTER_SAVE_ACTIONS, actualContents);<br /> }<br /><br /> @SuppressWarnings(</span><span style="color: rgb(42,0,255);">"restriction"</span><span style="color: rgb(0,0,0);">)<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> enableJavaSaveActions() {<br /> InstanceScope.INSTANCE.getNode(JavaUI.ID_PLUGIN).putBoolean(Constants.PERFORM_SAVE_ACTIONS_PREFERENCE, </span><span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">);<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> Map<String, String> cleanupPreferences = </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> HashMap<String, String>(<br /> org.eclipse.jdt.internal.ui.JavaPlugin<br /> .getDefault()<br /> .getCleanUpRegistry()<br /> .getDefaultOptions(<br /> org.eclipse.jdt.internal.corext.fix.CleanUpConstants.DEFAULT_SAVE_ACTION_OPTIONS)<br /> .getMap());<br /><br /> cleanupPreferences.put(org.eclipse.jdt.internal.corext.fix.CleanUpConstants.FORMAT_SOURCE_CODE,<br /> CleanUpOptions.TRUE);<br /> cleanupPreferences.put(org.eclipse.jdt.internal.corext.fix.CleanUpConstants.ORGANIZE_IMPORTS,<br /> CleanUpOptions.TRUE);<br /> cleanupPreferences.put(org.eclipse.jdt.internal.corext.fix.CleanUpConstants.CLEANUP_ON_SAVE_ADDITIONAL_OPTIONS,<br /> CleanUpOptions.TRUE);<br /> org.eclipse.jdt.internal.corext.fix.CleanUpPreferenceUtil.saveSaveParticipantOptions(InstanceScope.INSTANCE,<br /> cleanupPreferences);<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> IFolder createASourceFolder(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> String name) </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> CoreException {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IFolder aJavaSourceFolder = aJavaProject.getFolder(Path.fromPortableString(name));<br /> create(aJavaSourceFolder);<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">return</span><span style="color: rgb(0,0,0);"> aJavaSourceFolder;<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> IFolder createAPackage(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IFolder aJavaSourceFolder, </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> String name) </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> CoreException {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IFolder aJavaPackage = aJavaSourceFolder.getFolder(Path.fromPortableString(name));<br /> create(aJavaPackage);<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">return</span><span style="color: rgb(0,0,0);"> aJavaPackage;<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> create(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IFolder folder) </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> CoreException {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IContainer parent = folder.getParent();<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">if</span><span style="color: rgb(0,0,0);"> (parent.getType() == IResource.FOLDER && !parent.exists()) {<br /> create((IFolder) parent);<br /> }<br /> folder.create(</span><span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">, </span><span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">, NULL_PROGRESS_MONITOR);<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> IFile createAJavaFile(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IFolder aJavaPackage, </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> String name) </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> CoreException {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IFile aJavaFile = aJavaPackage.getFile(Path.fromPortableString(name));<br /> aJavaFile.create(</span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> ByteArrayInputStream(TEST_CLASS_BEFORE_SAVE_ACTIONS.getBytes()), </span><span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">,<br /> NULL_PROGRESS_MONITOR);<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">return</span><span style="color: rgb(0,0,0);"> aJavaFile;<br /> }<br /><br /> </span><span style="color: rgb(63,127,95);">// based on http://www.stateofflow.com/journal/66/creating-java-projects-programmatically<br /></span><span style="color: rgb(0,0,0);"> @SuppressWarnings(</span><span style="color: rgb(42,0,255);">"restriction"</span><span style="color: rgb(0,0,0);">)<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> IProject createAJavaProject(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> String name) </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> CoreException {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot();<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IProject project = root.getProject(name);<br /> project.create(NULL_PROGRESS_MONITOR);<br /> project.open(NULL_PROGRESS_MONITOR);<br /> org.eclipse.jdt.internal.ui.wizards.buildpaths.BuildPathsBlock.addJavaNature(project, </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> SubProgressMonitor(<br /> NULL_PROGRESS_MONITOR, 1));<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IJavaProject javaProject = JavaCore.create(project);<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> List<IClasspathEntry> entries = </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> ArrayList<IClasspathEntry>();<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">for</span><span style="color: rgb(0,0,0);"> (</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> IClasspathEntry entry : javaProject.getRawClasspath()) {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">if</span><span style="color: rgb(0,0,0);"> (entry.getEntryKind() == IClasspathEntry.CPE_SOURCE) {<br /> ((org.eclipse.jdt.internal.core.ClasspathEntry) entry).path = Path.fromPortableString(SOURCE_FOLDER);<br /> }<br /> entries.add(entry);<br /> }<br /> entries.add(JavaRuntime.getDefaultJREContainerEntry());<br /> javaProject.setRawClasspath(entries.toArray(</span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> IClasspathEntry[entries.size()]), NULL_PROGRESS_MONITOR);<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">return</span><span style="color: rgb(0,0,0);"> project;<br /> }<br />}<br /></span></span><br /></div><br /><br /><h4>The Feature</h4><br />Now that we have a tested plug-in, we will create an Eclipse feature to contain it for distribution. We can do practically all our configuration through the New Feature Project Wizard, except we want to put the feature project into a <em>features</em> subdirectory in the same way that we put our plug-in and fragment into the <em>plugins</em> subdirectory.<br /><br /><img alt="The New Feature Project wizard" src="http://farm7.static.flickr.com/6094/6236573969_93fca00579_z.jpg" /><br /><br /><h4>The Update Site</h4><br />Now that we have a tested plug-in and a feature to contain it, we will create an Eclipse update site for publishing the feature. In the New Update Site Project Wizard, we will again override the default location so that our update site project is in an <em>update-site</em> subdirectory, just as we separated our plug-in, fragment and feature into <em>plugins</em> and <em>features</em> subdirectories.<br /><br /><img alt="The New Update Site Project wizard" src="http://farm7.static.flickr.com/6052/6255218901_1fd2035ca1_z.jpg" /><br /><strong>NB:</strong> Whereas we may have multiple features or plug-ins for our project, we will have a single update site; thus the update-site project is not contained in a subfolder of <em>update-site</em>, but in this folder directly. <br /><br /><h4>Tycho</h4><br />Compiling, running integration tests and packaging an application entirely within an IDE does not scale to even a single programmer over time, let alone a team of programmers working on multiple plug-in projects. So far, the amount of ceremony for creating our menu contribution has been high, but the IDE has reduced a significant amount of the boilerplate. Before Tycho, the amount of ceremony and hackery required to get plugins, features and update sites packaged and unit and integration test suites running on a CI server had been prohibitively high. Tycho removes a significant amount of that pain.<br />Generating meaningful poms for our projects is as trivial as going into each of the <em>features</em>, <em>plugins</em> and <em>update-site</em> directories and running a Tycho goal.<br /><br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 11pt;"> mvn org.eclipse.tycho:tycho-pomgenerator-plugin:generate-poms -DgroupId=timezra.eclipse</span><br /></div><br /><br />We can combine some of the boilerplate in each of the subproject poms in an über-parent pom at the root of our workspace. We will also add the <a href="http://www.eclipse.org/indigo/">Indigo</a> p2 repository and a <a href="http://tycho.sonatype.org/targetplatformmanagement.html">target platform configuration resolver</a> since we are developing our Eclipse components Manifest-first.<br /><br /><em>pom.xml</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"</span><br /> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0"</span> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span>4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>timezra.eclipse<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>apply-save-actions-parent<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.0.0-SNAPSHOT<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">packaging</span><span style="color: rgb(0,128,128);">></span>pom<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">packaging</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">properties</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">tycho-version</span><span style="color: rgb(0,128,128);">></span>0.13.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">tycho-version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">properties</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">modules</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">module</span><span style="color: rgb(0,128,128);">></span>plugins<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">module</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">module</span><span style="color: rgb(0,128,128);">></span>features<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">module</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">module</span><span style="color: rgb(0,128,128);">></span>update-site<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">module</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">modules</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.eclipse.tycho<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>tycho-maven-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>${tycho-version}<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">extensions</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">extensions</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.eclipse.tycho<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>target-platform-configuration<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>${tycho-version}<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">resolver</span><span style="color: rgb(0,128,128);">></span>p2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">resolver</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repositories</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>indigo<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">layout</span><span style="color: rgb(0,128,128);">></span>p2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">layout</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://download.eclipse.org/releases/indigo/<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repositories</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br />We will also <a href="http://git.eclipse.org/c/tycho/org.eclipse.tycho.git/tree/tycho-demo/itp01/tycho.demo.itp01.tests/pom.xml">configure Tycho to use the UI test runner</a> for our integration test suite, as well as add any platform-specific runtime plug-in dependencies or configuration to the test fragment pom.<br /><br /><em>plugins/timezra.eclipse.apply_save_actions.tests/pom.xml</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"</span><br /> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0"</span> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span>4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">parent</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>timezra.eclipse<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>apply-save-actions-plugins-parent<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.0.0-SNAPSHOT<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">parent</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>timezra.eclipse<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>timezra.eclipse.apply_save_actions.tests<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.0.0-SNAPSHOT<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">packaging</span><span style="color: rgb(0,128,128);">></span>eclipse-test-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">packaging</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(63,95,191);"><!--</span><span style="color: rgb(63,95,191);"> Tell tycho to run PDE tests http://git.eclipse.org/c/tycho/org.eclipse.tycho.git/tree/tycho-demo/itp01/tycho.demo.itp01.tests/pom.xml </span><span style="color: rgb(63,95,191);">--></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">outputDirectory</span><span style="color: rgb(0,128,128);">></span>target/test-classes<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">outputDirectory</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.eclipse.tycho<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>tycho-surefire-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>${tycho-version}<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">useUIHarness</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">useUIHarness</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">profiles</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">profile</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>osx<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">activation</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span>java.vendor.url<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span>http://www.apple.com/<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">activation</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">pluginManagement</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.eclipse.tycho<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>tycho-surefire-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>${tycho-version}<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">argLine</span><span style="color: rgb(0,128,128);">></span>-XstartOnFirstThread<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">argLine</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">type</span><span style="color: rgb(0,128,128);">></span>p2-installable-unit<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">type</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>org.eclipse.jdt.launching.macosx<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">pluginManagement</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">profile</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">profiles</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><strong>NB:</strong> we would use <a href="http://timezra.blogspot.com/2010/05/tycho-tests-without-osgi.html">a different configuration</a> if our fragment contained unit-tests instead of integration tests.<br /><br /><h4>JAR signing</h4><br />If you do not have access to a certificate from a trusted authority, you can generate a self-signed certificate with 1-year validity by a command such as<br /><br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 11pt;"> keytool -genkey -alias _keystore_alias_ -keystore /path/to/keystore -validity 365</span><br /></div><br /><br />In order to sign the jars deployed to our update-site before release, we will add a new profile with a <a href="http://www.zeroturnaround.com/blog/building-eclipse-plug-ins-with-maven-3-and-tycho/">plug-in management configuration</a> to the über-parent pom.<br /><br /><em>pom.xml</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> ....<span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">profiles</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">profile</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>sign<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(63,95,191);"><!--</span><span style="color: rgb(63,95,191);"> To sign plug-ins and features, run: mvn -Psign -Djarsigner.keystore=<path> -Djarsigner.storepass=******* -Djarsigner.alias=<keyalias> clean package integration-test </span><span style="color: rgb(63,95,191);">--></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">pluginManagement</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.apache.maven.plugins<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>maven-jarsigner-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>sign<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span>sign<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>verify<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span>verify<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">pluginManagement</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">profile</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">profiles</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br />Similarly, we will <a href="http://www.zeroturnaround.com/blog/building-eclipse-plug-ins-with-maven-3-and-tycho/">configure the plug-ins and features parent poms for jar signing</a>.<br /><br /><em>plugins/pom.xml</em> and <em>features/pom.xml</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 11pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> ....<span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">profiles</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">profile</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>sign<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.apache.maven.plugins<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>maven-jarsigner-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">profile</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">profiles</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br /><h4>Publishing</h4><br />We are now ready to build and test our signed plug-ins and features and to package them in an update site for deployment.<br /><br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 11pt;"> mvn -Psign -Djarsigner.keystore=/path/to/keystore -Djarsigner.storepass=_keystore_password_ -Djarsigner.alias=_keystore_alias_ clean package integration-test</span><br /></div><br /><br />There will now be a fully deployable update site in <em>update-site/target/site</em>.<br />For this particular project, I distribute the contents of this directory to the <a href="http://pages.github.com/">gh-pages branch</a> of the <a href="https://github.com/timezra/save-actions-extensions">project</a> on github.<br />Since the <a href="http://timezra.github.com/save-actions-extensions/">update site for the project</a> is publicly-available and since I have an <a href="https://bugs.eclipse.org/bugs/">Eclipse Bugzilla login</a>, I can simply <a href="http://marketplace.eclipse.org/addcontent">add a new solution listing</a> to the <a href="http://marketplace.eclipse.org/">Eclipse Marketplace</a> to make the menu contribution even more discoverable by and accessible to Eclipse users.<br /><br /><h4>Conclusion</h4><br />This tutorial has provided the outline for the workflow of taking an idea for a single-featured Eclipse contribution from inception to delivery in a very short amount of time. While Eclipse tooling has for years provided the means to perform the tasks of plug-in, fragment, feature and update site publishing entirely within the IDE, it is the Tycho project that lowers the barrier to entry for scaling out plug-in development by making the build and test process far simpler to automate and to configure than other PDE-based build systems. Along the way, we have explored JAR signing and uploading of content to github and to the Eclipse Marketplace, and we have hopefully developed a menu contribution that others will find useful in their own projects.<br /><br /><img alt="The source submenu contribution for applying save actions in batch mode" src="http://farm7.static.flickr.com/6060/6237098352_04757e5682_z.jpg" />Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com0tag:blogger.com,1999:blog-106449775438946661.post-16570682267788573102011-10-05T09:54:00.000-07:002011-10-11T09:43:41.188-07:00JPA Callbacks With Hibernate<h4>Goal:</h4><br />The purpose of this blog entry is to provide one solution for using <a href="http://stackoverflow.com/questions/4133287/preupdate-and-prepersist-in-hibernate-jpa-using-session">JPA Annotations with Hibernate but without using the Hibernate EntityManager</a>. Thanks to Ben Macfarlane for posing this problem and for doing the groundwork for me to come up with a somewhat simple solution.<br /><br /><h4>tl;dr</h4><br />If you want to look right away at working code that compares the configuration of JPA callbacks with the EntityManager and the Hibernate SessionFactory, a <a href="https://github.com/timezra/hibernate-jpa-callbacks">sample project</a> based on this tutorial is available.<br /><br /><h4>Create a Maven Project:</h4><br />We will start with a boilerplate Maven project that includes dependencies on Spring, Hibernate and JUnit.<br /><em>pom.xml</em><br /><div style="overflow:auto;height:250px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0"</span> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span><br /> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span>4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>timezra.hibernate<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>callbacks<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>0.0.1-SNAPSHOT<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">description</span><span style="color: rgb(0,128,128);">></span>Demo for using JPA callbacks with hibernate<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">description</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">properties</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">maven.compiler.source</span><span style="color: rgb(0,128,128);">></span>1.6<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">maven.compiler.source</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">maven.compiler.target</span><span style="color: rgb(0,128,128);">></span>1.6<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">maven.compiler.target</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">properties</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>spring-orm<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.6.RELEASE<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>cglib<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>cglib-nodep<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.2.2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.hibernate<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>hibernate-core<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.6.7.Final<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.hibernate<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>hibernate-annotations<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.5.6-Final<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.hibernate<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>hibernate-validator<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.1.0.GA<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.javassist<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>javassist<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.15.0-GA<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>com.h2database<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>h2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.3.160<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>commons-dbcp<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>commons-dbcp<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.4<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>junit<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>junit<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>4.10<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>spring-test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.6.RELEASE<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><br /><h4>Create a Domain and Domain Access:</h4><br />Our domain can be as simple as a single POJO that uses javax.persistence annotations such as <em>@PrePersist</em>, <em>@PreUpdate</em> and <em>@PostLoad</em>.<br /><em>src/main/java/timezra/hibernate/callbacks/domain/Author.java</em><br /><div style="overflow:auto;height:1160px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span><span style="color: rgb(0,0,0);"> timezra.hibernate.callbacks.domain;<br /><br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> java.util.Calendar;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> java.util.Date;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> java.util.Locale;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> javax.persistence.Entity;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> javax.persistence.GeneratedValue;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> javax.persistence.GenerationType;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> javax.persistence.Id;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> javax.persistence.PostLoad;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> javax.persistence.PrePersist;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> javax.persistence.PreUpdate;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> javax.persistence.Table;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> javax.persistence.Transient;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> javax.persistence.UniqueConstraint;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.hibernate.validator.NotNull;<br /><br />@Entity<br />@Table(uniqueConstraints = @UniqueConstraint(columnNames = Author.NAME_ATTRIBUTE))<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);"> Author {<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">static</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> String NAME_ATTRIBUTE = </span><span style="color: rgb(42,0,255);">"name"</span><span style="color: rgb(0,0,0);">;<br /><br /> @Id<br /> @GeneratedValue(strategy = GenerationType.SEQUENCE)<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> Long id;<br /> @NotNull<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> String name;<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> Date dateOfBirth;<br /> @Transient<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> Integer age;<br /> @NotNull<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> Date dateCreated;<br /> @NotNull<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> Date lastUpdated;<br /><br /> @PrePersist<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> prePersist() {<br /> dateCreated = lastUpdated = </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> Date();<br /> }<br /><br /> @PreUpdate<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> preUpdate() {<br /> lastUpdated = </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> Date();<br /> }<br /><br /> @PostLoad<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> postLoad() {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">if</span><span style="color: rgb(0,0,0);"> (dateOfBirth != </span><span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">) {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> Calendar now = Calendar.getInstance(Locale.getDefault());<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">int</span><span style="color: rgb(0,0,0);"> thisYear = now.get(Calendar.YEAR);<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">int</span><span style="color: rgb(0,0,0);"> thisDay = now.get(Calendar.DAY_OF_YEAR);<br /> now.setTime(dateOfBirth);<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">int</span><span style="color: rgb(0,0,0);"> birthYear = now.get(Calendar.YEAR);<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">int</span><span style="color: rgb(0,0,0);"> birthDay = now.get(Calendar.DAY_OF_YEAR);<br /> age = thisYear - birthYear - (birthDay > thisDay ? 1 : 0);<br /> }<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> Long getId() {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">return</span><span style="color: rgb(0,0,0);"> id;<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> Date getDateCreated() {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">return</span><span style="color: rgb(0,0,0);"> dateCreated;<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> Date getLastUpdated() {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">return</span><span style="color: rgb(0,0,0);"> lastUpdated;<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> Integer getAge() {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">return</span><span style="color: rgb(0,0,0);"> age;<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> Date getDateOfBirth() {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">return</span><span style="color: rgb(0,0,0);"> dateOfBirth;<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> setDateOfBirth(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> Date dateOfBirth) {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.dateOfBirth = dateOfBirth;<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> String getName() {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">return</span><span style="color: rgb(0,0,0);"> name;<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> setName(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> String name) {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.name = name;<br /> }<br />}<br /></span></span><br /></div><br /><br />A DAO and Service can provide access into our domain.<br /><em>src/main/java/timezra/hibernate/callbacks/dao/AuthorDAO.java</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span><span style="color: rgb(0,0,0);"> timezra.hibernate.callbacks.dao;<br /><br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> javax.annotation.Resource;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.hibernate.Session;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.hibernate.SessionFactory;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.hibernate.criterion.Restrictions;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.springframework.stereotype.Repository;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> timezra.hibernate.callbacks.domain.Author;<br /><br />@Repository<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);"> AuthorDAO {<br /><br /> @Resource<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> SessionFactory sessionFactory;<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> create(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> Author a) {<br /> getSession().save(a);<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> Author findByName(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> String name) {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">return</span><span style="color: rgb(0,0,0);"> (Author) getSession().createCriteria(Author.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">) </span><span style="color: rgb(63,127,95);">//<br /></span><span style="color: rgb(0,0,0);"> .add(Restrictions.eq(Author.NAME_ATTRIBUTE, name)) </span><span style="color: rgb(63,127,95);">//<br /></span><span style="color: rgb(0,0,0);"> .uniqueResult();<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> update(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> Author a) {<br /> getSession().update(a);<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> delete(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> Author a) {<br /> getSession().delete(a);<br /> }<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> Session getSession() {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">return</span><span style="color: rgb(0,0,0);"> sessionFactory.getCurrentSession();<br /> }<br />}<br /></span></span><br /></div><br /><br /><em>src/main/java/timezra/hibernate/callbacks/service/AuthorService.java</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span><span style="color: rgb(0,0,0);"> timezra.hibernate.callbacks.service;<br /><br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> javax.annotation.Resource;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.springframework.stereotype.Service;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.springframework.transaction.annotation.Propagation;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.springframework.transaction.annotation.Transactional;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> timezra.hibernate.callbacks.dao.AuthorDAO;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> timezra.hibernate.callbacks.domain.Author;<br /><br />@Service<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);"> AuthorService {<br /><br /> @Resource<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> AuthorDAO authorDAO;<br /><br /> @Transactional<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> create(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> Author a) {<br /> authorDAO.create(a);<br /> }<br /><br /> @Transactional<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> update(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> Author a) {<br /> authorDAO.update(a);<br /> }<br /><br /> @Transactional<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> delete(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> Author a) {<br /> authorDAO.delete(a);<br /> }<br /><br /> @Transactional(propagation = Propagation.SUPPORTS)<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> Author findByName(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> String name) {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">return</span><span style="color: rgb(0,0,0);"> authorDAO.findByName(name);<br /> }<br />}<br /></span></span><br /></div><br /><br /><h4>Wire It Together With Spring:</h4><br />We will use Spring to glue all our components together and to manage their lifecycles.<br /><em>src/main/resources/applicationContext.xml</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">beans</span> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/beans"</span><br /> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span> <span style="color: rgb(127,0,127);">xmlns:context</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/context"</span><br /> <span style="color: rgb(127,0,127);">xmlns:tx</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/tx"</span><br /> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"<br /> http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd<br /> http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd<br /> http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"</span><span style="color: rgb(0,128,128);">></span><br /><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"dataSource"</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.apache.commons.dbcp.BasicDataSource"</span><br /> <span style="color: rgb(127,0,127);">destroy-method</span>=<span style="font-style: italic; color: rgb(42,0,255);">"close"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"driverClassName"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.h2.Driver"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"url"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jdbc:h2:test"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"username"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"sa"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"password"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">""</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"sessionFactory"</span><br /> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"dataSource"</span> <span style="color: rgb(127,0,127);">ref</span>=<span style="font-style: italic; color: rgb(42,0,255);">"dataSource"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"packagesToScan"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">list</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span>timezra.hibernate.callbacks.domain<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">list</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernateProperties"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">props</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.dialect"</span><span style="color: rgb(0,128,128);">></span>org.hibernate.dialect.H2Dialect<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.hbm2ddl.auto"</span><span style="color: rgb(0,128,128);">></span>update<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">props</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"transactionManager"</span><br /> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.orm.hibernate3.HibernateTransactionManager"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"sessionFactory"</span> <span style="color: rgb(127,0,127);">ref</span>=<span style="font-style: italic; color: rgb(42,0,255);">"sessionFactory"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">context:component-scan</span> <span style="color: rgb(127,0,127);">base-package</span>=<span style="font-style: italic; color: rgb(42,0,255);">"timezra.hibernate.callbacks"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">context:annotation-config</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">tx:annotation-driven</span> <span style="color: rgb(0,128,128);">/></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">beans</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><br /><h4>Test The JPA Callbacks:</h4><br />Finally we can test that the annotated methods are called at the expected times during Hibernate lifecycle events.<br /><em>src/test/java/timezra/hibernate/callbacks/domain/AuthorTest.java</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span><span style="color: rgb(0,0,0);"> timezra.hibernate.callbacks.domain;<br /><br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">static</span><span style="color: rgb(0,0,0);"> org.junit.Assert.assertEquals;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">static</span><span style="color: rgb(0,0,0);"> org.junit.Assert.assertNotNull;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">static</span><span style="color: rgb(0,0,0);"> org.junit.Assert.assertNull;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">static</span><span style="color: rgb(0,0,0);"> org.junit.Assert.assertTrue;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> java.util.Calendar;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> java.util.Date;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> java.util.Locale;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> javax.annotation.Resource;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.junit.After;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.junit.Before;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.junit.Test;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.junit.runner.RunWith;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.springframework.test.context.ContextConfiguration;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.springframework.test.context.junit4.SpringJUnit4ClassRunner;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> timezra.hibernate.callbacks.service.AuthorService;<br /><br />@RunWith(SpringJUnit4ClassRunner.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">)<br />@ContextConfiguration(</span><span style="color: rgb(42,0,255);">"/applicationContext.xml"</span><span style="color: rgb(0,0,0);">)<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);"> AuthorTest {<br /><br /> @Resource<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> AuthorService authorService;<br /><br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> Author testAuthor;<br /><br /> @Before<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> setup() {<br /> testAuthor = </span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> Author();<br /> testAuthor.setName(</span><span style="color: rgb(42,0,255);">"timezra"</span><span style="color: rgb(0,0,0);">);<br /> authorService.create(testAuthor);<br /> }<br /><br /> @After<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> tearDown() {<br /> authorService.delete(testAuthor);<br /> }<br /><br /> @Test<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> theCreationDateIsSetAutomatically() {<br /> assertNotNull(testAuthor.getDateCreated());<br /> }<br /><br /> @Test<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> theUpdatedDateIsSetAutomaticallyOnCreation() {<br /> assertEquals(testAuthor.getDateCreated(), testAuthor.getLastUpdated());<br /> }<br /><br /> @Test<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> theUpdatedDateIsSetAutomaticallyOnUpdate() {<br /> testAuthor.setDateOfBirth(</span><span style="font-weight: bold; color: rgb(127,0,85);">new</span><span style="color: rgb(0,0,0);"> Date());<br /><br /> authorService.update(testAuthor);<br /><br /> assertTrue(testAuthor.getDateCreated().before(testAuthor.getLastUpdated()));<br /> }<br /><br /> @Test<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> theAgeIsSetAutomaticallyWhenTheAuthorIsLoaded() {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> Integer expectedAge = 42;<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> Calendar birthDate = Calendar.getInstance(Locale.getDefault());<br /> birthDate.add(Calendar.YEAR, -expectedAge);<br /> testAuthor.setDateOfBirth(birthDate.getTime());<br /> authorService.update(testAuthor);<br /><br /> assertNull(testAuthor.getAge());<br /> assertEquals(expectedAge, authorService.findByName(testAuthor.getName()).getAge());<br /> }<br />}<br /></span></span><br /></div><br />We should expect all these tests to fail with a Hibernate validation Exception.<br /><img alt="JUnit Test Failures for JPA Annotations" src="http://farm7.static.flickr.com/6052/6214874464_d90770c677_z.jpg" /><br /><br /><h4>Update Project Dependencies:</h4><br />Fortunately, the <em>hibernate-entitymanager</em> component provides a set of JPA lifecycle listeners that can be used independent of the Hibernate EntityManager, so we will update our project dependencies.<br /><em>pom.xml</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> ....<span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.hibernate<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>hibernate-entitymanager<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.6.7.Final<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><strong>NB:</strong> for this sample code, the version must be 3.6.x+ in order to access the ReflectionManager from the Hibernate configuration.<br /><br /><h4>Register Hibernate Event Listeners:</h4><br />We must manually tie the JPA lifecycle listeners to Hibernate events, much as the org.hibernate.ejb.EventListenerConfigurator#configure would if the Hibernate EntityManager were used.<br /><em>src/main/java/timezra/hibernate/callbacks/domain/EntityCallbackHandlerInitializer.java</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span><span style="color: rgb(0,0,0);"> timezra.hibernate.callbacks.dao;<br /><br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> java.util.Iterator;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> javax.annotation.PostConstruct;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> javax.annotation.Resource;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.hibernate.annotations.common.reflection.ReflectionManager;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.hibernate.cfg.Configuration;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.hibernate.ejb.event.EntityCallbackHandler;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.hibernate.mapping.PersistentClass;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean;<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">import</span><span style="color: rgb(0,0,0);"> org.springframework.stereotype.Component;<br /><br />@Component<br /></span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);"> EntityCallbackHandlerInitializer {<br /><br /> @Resource<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> AnnotationSessionFactoryBean annotationSessionFactory;<br /><br /> @Resource<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">private</span><span style="color: rgb(0,0,0);"> EntityCallbackHandler entityCallbackHandler;<br /><br /> @PostConstruct<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">public</span><span style="color: rgb(0,0,0);"> </span><span style="font-weight: bold; color: rgb(127,0,85);">void</span><span style="color: rgb(0,0,0);"> init() </span><span style="font-weight: bold; color: rgb(127,0,85);">throws</span><span style="color: rgb(0,0,0);"> ClassNotFoundException {<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> Configuration configuration = annotationSessionFactory.getConfiguration();<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> ReflectionManager reflectionManager = configuration.getReflectionManager();<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">final</span><span style="color: rgb(0,0,0);"> Iterator<PersistentClass> classMappings = configuration.getClassMappings();<br /> </span><span style="font-weight: bold; color: rgb(127,0,85);">while</span><span style="color: rgb(0,0,0);"> (classMappings.hasNext()) {<br /> entityCallbackHandler.add(<br /> reflectionManager.classForName(classMappings.next().getClassName(), </span><span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.getClass()),<br /> reflectionManager);<br /> }<br /> }<br />}</span></span><br /></div><br /><br />Finally, we will update the Hibernate configuration in the Spring context to use these event listeners. This configuration is based off a similar solution on the <a href="http://forum.springsource.org/showthread.php?54566-Hibernate-3.2-Persistent-Lifecycle-annotations-not-work">Spring Forum</a>.<br /><em>src/main/resources/applicationContext.xml</em><br /><div style="overflow:auto;padding:5px;background-color:white;border-style:dashed;border-width:1px"><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">beans</span> ....<span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"sessionFactory"</span> ....<span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"eventListeners"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">map</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">entry</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"save"</span> <span style="color: rgb(127,0,127);">value-ref</span>=<span style="font-style: italic; color: rgb(42,0,255);">"saveEventListener"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">entry</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"flush-entity"</span> <span style="color: rgb(127,0,127);">value-ref</span>=<span style="font-style: italic; color: rgb(42,0,255);">"flushEntityEventListener"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">entry</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"post-load"</span> <span style="color: rgb(127,0,127);">value-ref</span>=<span style="font-style: italic; color: rgb(42,0,255);">"postLoadEventListener"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">map</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"saveEventListener"</span> <span style="color: rgb(127,0,127);">parent</span>=<span style="font-style: italic; color: rgb(42,0,255);">"callbackHandlerEventListener"</span><br /> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.hibernate.ejb.event.EJB3SaveEventListener"</span> <span style="color: rgb(0,128,128);">/></span><br /> <br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"flushEntityEventListener"</span> <span style="color: rgb(127,0,127);">parent</span>=<span style="font-style: italic; color: rgb(42,0,255);">"callbackHandlerEventListener"</span><br /> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.hibernate.ejb.event.EJB3FlushEntityEventListener"</span> <span style="color: rgb(0,128,128);">/></span><br /> <br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"postLoadEventListener"</span> <span style="color: rgb(127,0,127);">parent</span>=<span style="font-style: italic; color: rgb(42,0,255);">"callbackHandlerEventListener"</span><br /> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.hibernate.ejb.event.EJB3PostLoadEventListener"</span> <span style="color: rgb(0,128,128);">/></span><br /><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"entityCallbackHandler"</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.hibernate.ejb.event.EntityCallbackHandler"</span> <span style="color: rgb(0,128,128);">/></span><br /><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"callbackHandlerEventListener"</span> <span style="color: rgb(127,0,127);">abstract</span>=<span style="font-style: italic; color: rgb(42,0,255);">"true"</span><br /> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.hibernate.ejb.event.CallbackHandlerConsumer"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"callbackHandler"</span> <span style="color: rgb(127,0,127);">ref</span>=<span style="font-style: italic; color: rgb(42,0,255);">"entityCallbackHandler"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">beans</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><strong>NB:</strong> This configuration is for a subset of javax.persistence annotations and should be considered a starting point. It is up to the reader to configure Hibernate to use other other listeners in the org.hibernate.ejb.event package if the enablement of more JPA annotations is desired. For the purpose of this tutorial, the three listeners above are sufficient.<br /><br />The test cases now succeed.<br /><br /><h4>Conclusion:</h4><br />The purpose of this tutorial has been to demonstrate that, with minimal code and configuration additional to what is necessary for a standard Maven/Spring/Hibernate project, Hibernate can detect JPA annotations and tie them to its persistence lifecycle events. Along the way, we have also developed a simple methodology for testing that JPA annotated methods are called when expected, and this methodology can be used to extend the sample code to cover the remaining javax.persistence annotations not specified in this tutorial.<br /><br /><a href="https://github.com/timezra/hibernate-jpa-callbacks">Sample code</a> based on this tutorial is also available.Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com3tag:blogger.com,1999:blog-106449775438946661.post-86508190750382232702010-05-22T01:13:00.000-07:002010-05-22T01:29:07.116-07:00Testing Stereotype Attribute RegEx Constraints<h4>Goal:</h4><br />Suppose that we have a <a href="http://timezra.blogspot.com/2010/04/regex-to-validate-uml-stereotype.html">UML profile that contains a stereotype with an attribute of a custom data type constrained by a regular expression</a>. This tutorial steps through one way to automate tests that exercise this restriction.<br /><br /><h4>Create a UML Profile:</h4><br />We can use the instructions from <a href="http://timezra.blogspot.com/2010/04/regex-to-validate-uml-stereotype.html">a previous tutorial</a> to create a UML profile with a restricted data type. In our case, a Contact is an Actor who has a US phone number. We can call our profile <em>Contact.profile.uml</em>:<br /><div style="overflow:auto;width:60%;height:250px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xmi:XMI</span> <span style="color: rgb(127,0,127);">xmi:version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"2.1"</span> <span style="color: rgb(127,0,127);">xmlns:xmi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://schema.omg.org/spec/XMI/2.1"</span> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span> <span style="color: rgb(127,0,127);">xmlns:Ecore</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.eclipse.org/uml2/schemas/Ecore/5"</span> <span style="color: rgb(127,0,127);">xmlns:ecore</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.eclipse.org/emf/2002/Ecore"</span> <span style="color: rgb(127,0,127);">xmlns:uml</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.eclipse.org/uml2/3.0.0/UML"</span> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.eclipse.org/uml2/schemas/Ecore/5 pathmap://UML_PROFILES/Ecore.profile.uml#_z1OFcHjqEdy8S4Cr8Rc_NA"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">uml:Profile</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_-8vWsEz2Ed-q5fB8PwONew"</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"ContactProfile"</span> <span style="color: rgb(127,0,127);">metaclassReference</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_Q-rN8Ez-Ed-q5fB8PwONew"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">eAnnotations</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_TjG80GI3Ed-E2et4hPKZEg"</span> <span style="color: rgb(127,0,127);">source</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.eclipse.org/uml2/2.0.0/UML"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">contents</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"ecore:EPackage"</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_TjJZEGI3Ed-E2et4hPKZEg"</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"RegexValidation"</span> <span style="color: rgb(127,0,127);">nsURI</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http:///schemas/RegexValidation/_Til_cGI3Ed-E2et4hPKZEg/0"</span> <span style="color: rgb(127,0,127);">nsPrefix</span>=<span style="font-style: italic; color: rgb(42,0,255);">"RegexValidation"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">eClassifiers</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"ecore:EClass"</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_TjJZEWI3Ed-E2et4hPKZEg"</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"Contact"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">eAnnotations</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_TjJZEmI3Ed-E2et4hPKZEg"</span> <span style="color: rgb(127,0,127);">source</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.eclipse.org/uml2/2.0.0/UML"</span> <span style="color: rgb(127,0,127);">references</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_KxZQgEz3Ed-q5fB8PwONew"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">eStructuralFeatures</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"ecore:EReference"</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_TjJZE2I3Ed-E2et4hPKZEg"</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"base_Actor"</span> <span style="color: rgb(127,0,127);">ordered</span>=<span style="font-style: italic; color: rgb(42,0,255);">"false"</span> <span style="color: rgb(127,0,127);">lowerBound</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">eType</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"ecore:EClass"</span> <span style="color: rgb(127,0,127);">href</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.eclipse.org/uml2/3.0.0/UML#//Actor"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">eStructuralFeatures</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">eStructuralFeatures</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"ecore:EAttribute"</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_TjJZFWI3Ed-E2et4hPKZEg"</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"PhoneNumber"</span> <span style="color: rgb(127,0,127);">ordered</span>=<span style="font-style: italic; color: rgb(42,0,255);">"false"</span> <span style="color: rgb(127,0,127);">lowerBound</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1"</span> <span style="color: rgb(127,0,127);">eType</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_TjJZF2I3Ed-E2et4hPKZEg"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">eClassifiers</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">eClassifiers</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"ecore:EDataType"</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_TjJZF2I3Ed-E2et4hPKZEg"</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"USPhoneNumberType"</span> <span style="color: rgb(127,0,127);">instanceClassName</span>=<span style="font-style: italic; color: rgb(42,0,255);">"java.lang.String"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">eAnnotations</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_TjJZGGI3Ed-E2et4hPKZEg"</span> <span style="color: rgb(127,0,127);">source</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.eclipse.org/uml2/2.0.0/UML"</span> <span style="color: rgb(127,0,127);">references</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_i7slcE0EEd-q5fB8PwONew"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">eAnnotations</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_TjJZGWI3Ed-E2et4hPKZEg"</span> <span style="color: rgb(127,0,127);">source</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http:///org/eclipse/emf/ecore/util/ExtendedMetaData"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">details</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_TjJZGmI3Ed-E2et4hPKZEg"</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"baseType"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.eclipse.org/emf/2003/XMLType#string"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">details</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_TjJZG2I3Ed-E2et4hPKZEg"</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"pattern"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">details</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_TjJZHGI3Ed-E2et4hPKZEg"</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"name"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"USPhoneNumberType"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">eAnnotations</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">eClassifiers</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">eClassifiers</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"ecore:EDataType"</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_TjJZHWI3Ed-E2et4hPKZEg"</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UMLPrimitiveTypes_String"</span> <span style="color: rgb(127,0,127);">instanceClassName</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UMLPrimitiveTypes_String"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">eAnnotations</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_TjJZHmI3Ed-E2et4hPKZEg"</span> <span style="color: rgb(127,0,127);">source</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.eclipse.org/uml2/2.0.0/UML"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">references</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"uml:PrimitiveType"</span> <span style="color: rgb(127,0,127);">href</span>=<span style="font-style: italic; color: rgb(42,0,255);">"pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#String"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">eAnnotations</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">eClassifiers</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">contents</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">eAnnotations</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">elementImport</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_-_cFYEz2Ed-q5fB8PwONew"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">importedElement</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"uml:PrimitiveType"</span> <span style="color: rgb(127,0,127);">href</span>=<span style="font-style: italic; color: rgb(42,0,255);">"pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#Boolean"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">elementImport</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">elementImport</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_-_koQEz2Ed-q5fB8PwONew"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">importedElement</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"uml:PrimitiveType"</span> <span style="color: rgb(127,0,127);">href</span>=<span style="font-style: italic; color: rgb(42,0,255);">"pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#String"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">elementImport</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">elementImport</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_-_koQUz2Ed-q5fB8PwONew"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">importedElement</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"uml:PrimitiveType"</span> <span style="color: rgb(127,0,127);">href</span>=<span style="font-style: italic; color: rgb(42,0,255);">"pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#UnlimitedNatural"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">elementImport</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">elementImport</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_-_koQkz2Ed-q5fB8PwONew"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">importedElement</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"uml:PrimitiveType"</span> <span style="color: rgb(127,0,127);">href</span>=<span style="font-style: italic; color: rgb(42,0,255);">"pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#Integer"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">elementImport</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">elementImport</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_Q-rN8Ez-Ed-q5fB8PwONew"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">importedElement</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"uml:Class"</span> <span style="color: rgb(127,0,127);">href</span>=<span style="font-style: italic; color: rgb(42,0,255);">"pathmap://UML_METAMODELS/UML.metamodel.uml#Actor"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">elementImport</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">packagedElement</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"uml:Stereotype"</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_KxZQgEz3Ed-q5fB8PwONew"</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"Contact"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">ownedAttribute</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_kIBdYkz-Ed-q5fB8PwONew"</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"base_Actor"</span> <span style="color: rgb(127,0,127);">association</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_kIBdYEz-Ed-q5fB8PwONew"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">type</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"uml:Class"</span> <span style="color: rgb(127,0,127);">href</span>=<span style="font-style: italic; color: rgb(42,0,255);">"pathmap://UML_METAMODELS/UML.metamodel.uml#Actor"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">ownedAttribute</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">ownedAttribute</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_XBEfIE0HEd-q5fB8PwONew"</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"PhoneNumber"</span> <span style="color: rgb(127,0,127);">type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_i7slcE0EEd-q5fB8PwONew"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">packagedElement</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">packagedElement</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"uml:Extension"</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_kIBdYEz-Ed-q5fB8PwONew"</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"Actor_Contact"</span> <span style="color: rgb(127,0,127);">memberEnd</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_kIBdYUz-Ed-q5fB8PwONew _kIBdYkz-Ed-q5fB8PwONew"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">ownedEnd</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"uml:ExtensionEnd"</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_kIBdYUz-Ed-q5fB8PwONew"</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"extension_Contact"</span> <span style="color: rgb(127,0,127);">type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_KxZQgEz3Ed-q5fB8PwONew"</span> <span style="color: rgb(127,0,127);">aggregation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"composite"</span> <span style="color: rgb(127,0,127);">association</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_kIBdYEz-Ed-q5fB8PwONew"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">packagedElement</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">packagedElement</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"uml:PrimitiveType"</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_i7slcE0EEd-q5fB8PwONew"</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"USPhoneNumberType"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">eAnnotations</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_xj3IsE0EEd-q5fB8PwONew"</span> <span style="color: rgb(127,0,127);">source</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http:///org/eclipse/emf/ecore/util/ExtendedMetaData"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">details</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_BRrscE0FEd-q5fB8PwONew"</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"name"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"USPhoneNumberType"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">details</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_EECfUE0FEd-q5fB8PwONew"</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"baseType"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.eclipse.org/emf/2003/XMLType#string"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">details</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_GVdvYE0FEd-q5fB8PwONew"</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"pattern"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">eAnnotations</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">generalization</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_oZx-wE0EEd-q5fB8PwONew"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">general</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"uml:PrimitiveType"</span> <span style="color: rgb(127,0,127);">href</span>=<span style="font-style: italic; color: rgb(42,0,255);">"pathmap://UML_LIBRARIES/UMLPrimitiveTypes.library.uml#String"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">generalization</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">packagedElement</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">profileApplication</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_NlBQ4E0GEd-q5fB8PwONew"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">eAnnotations</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_NlBQ4U0GEd-q5fB8PwONew"</span> <span style="color: rgb(127,0,127);">source</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.eclipse.org/uml2/2.0.0/UML"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">references</span> <span style="color: rgb(127,0,127);">xmi:type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"ecore:EPackage"</span> <span style="color: rgb(127,0,127);">href</span>=<span style="font-style: italic; color: rgb(42,0,255);">"pathmap://UML_PROFILES/Ecore.profile.uml#_z1OFcHjqEdy8S4Cr8Rc_NA"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">eAnnotations</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">appliedProfile</span> <span style="color: rgb(127,0,127);">href</span>=<span style="font-style: italic; color: rgb(42,0,255);">"pathmap://UML_PROFILES/Ecore.profile.uml#_0"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">profileApplication</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">uml:Profile</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">Ecore:EDataType</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_ZFV5cE0GEd-q5fB8PwONew"</span> <span style="color: rgb(127,0,127);">instanceClassName</span>=<span style="font-style: italic; color: rgb(42,0,255);">"java.lang.String"</span> <span style="color: rgb(127,0,127);">base_PrimitiveType</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_i7slcE0EEd-q5fB8PwONew"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">Ecore:EDataType</span> <span style="color: rgb(127,0,127);">xmi:id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"_QE9r0E0LEd-q5fB8PwONew"</span><span style="color: rgb(0,128,128);">/></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">xmi:XMI</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div> <br /><br /><h4>Load the Profile Programmatically:</h4><br />Suppose we need to access our profile from another Eclipse plug-in to create Contacts programmatically. In a <em>plugins</em> parent directory, we will then create a new Java Plug-in project, here called <em>timezra.blog.uml_regex_validation.resources</em>, and it will provide access to this profile from its plug-in Activator.<br />We can specify metadata for the plug-in in our META-INF/MANIFEST.MF:<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,0,0);">Manifest-Version</span><span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(42,0,255);">1.0</span><br /><span style="color: rgb(0,0,0);">Bundle-ManifestVersion</span><span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(42,0,255);">2</span><br /><span style="color: rgb(0,0,0);">Bundle-Name</span><span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(42,0,255);">UML</span> <span style="color: rgb(42,0,255);">Regex</span> <span style="color: rgb(42,0,255);">Validation</span> <span style="color: rgb(42,0,255);">Resources</span><br /><span style="color: rgb(0,0,0);">Bundle-SymbolicName</span><span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(42,0,255);">timezra.blog.uml_regex_validation.resources</span><br /><span style="color: rgb(0,0,0);">Bundle-Version</span><span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(42,0,255);">1.0.0.qualifier</span><br /><span style="color: rgb(0,0,0);">Bundle-Activator</span><span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(42,0,255);">timezra.blog.uml_regex_validation.resources.Activator</span><br /><span style="color: rgb(0,0,0);">Bundle-Vendor</span><span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(42,0,255);">Timezra</span><br /><span style="color: rgb(0,0,0);">Require-Bundle</span><span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(42,0,255);">org.eclipse.core.runtime;bundle-version</span><span style="color: rgb(0,0,0);">=</span><span style="color: rgb(42,0,255);">"[3.5.0,4.0.0)",</span><br /><span style="color: rgb(0,0,0);"> org.eclipse.emf.ecore;bundle-version</span><span style="color: rgb(0,0,0);">=</span><span style="color: rgb(42,0,255);">"[2.5.0,3.0.0)"</span><br /><span style="color: rgb(0,0,0);">Bundle-RequiredExecutionEnvironment</span><span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(42,0,255);">J2SE-1.5</span><br /><span style="color: rgb(0,0,0);">Bundle-ActivationPolicy</span><span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(42,0,255);">lazy</span><br /></span><br /></div> <br /><br />We also want to create an additional source directory called <em>profiles</em>. We can put our <em>Contact.profile.uml</em> file in this directory so that it can be loaded from the classpath in our tests.<br /><br />Our <em>timezra.blog.uml_regex_validation.resources.Activator.java</em> will handle loading the profile from a resource set:<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.uml_regex_validation.resources;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.core.runtime.Plugin;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.emf.common.util.URI;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.emf.ecore.resource.Resource;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.emf.ecore.resource.ResourceSet;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.osgi.framework.BundleContext;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">Activator</span> <span style="font-weight: bold; color: rgb(127,0,85);">extends</span> <span style="color: rgb(0,0,0);">Plugin</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">PLUGIN_ID</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"timezra.blog.uml_regex_validation.resources"</span><span style="color: rgb(0,0,0);">;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">Activator</span> <span style="color: rgb(0,0,0);">plugin;</span><br /><br /> <span style="color: rgb(0,0,0);">@Override</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">start(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">BundleContext</span> <span style="color: rgb(0,0,0);">context)</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">super</span><span style="color: rgb(0,0,0);">.start(context);</span><br /> <span style="color: rgb(0,0,0);">plugin</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Override</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">stop(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">BundleContext</span> <span style="color: rgb(0,0,0);">context)</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">plugin</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">super</span><span style="color: rgb(0,0,0);">.stop(context);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">Activator</span> <span style="color: rgb(0,0,0);">getDefault()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">plugin;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Resource</span> <span style="color: rgb(0,0,0);">loadProfile(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">ResourceSet</span> <span style="color: rgb(0,0,0);">resourceSet)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">resourceSet.getResource(createURIFor(</span><span style="color: rgb(42,0,255);">"profiles/Contact.profile.uml"</span><span style="color: rgb(0,0,0);">),</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">URI</span> <span style="color: rgb(0,0,0);">createURIFor(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">resource)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">URI.createPlatformPluginURI(String.format(</span><span style="color: rgb(42,0,255);">"/%s/%s"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">PLUGIN_ID,</span> <span style="color: rgb(0,0,0);">resource),</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div> <br /><br /><h4>Test with a Fragment:</h4><br />Now that we have a way to load the UML profile programmatically, we can create a test Fragment as a sibling to the functional bundle in the <em>plugins</em> directory. <br />We will call this Fragment <em>timezra.blog.uml_regex_validation.resources.tests</em>, and we will again declare plug-in metadata in the <em>META-INF/MANIFEST.MF</em>:<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,0,0);">Manifest-Version</span><span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(42,0,255);">1.0</span><br /><span style="color: rgb(0,0,0);">Bundle-ManifestVersion</span><span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(42,0,255);">2</span><br /><span style="color: rgb(0,0,0);">Bundle-Name</span><span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(42,0,255);">UML</span> <span style="color: rgb(42,0,255);">Regex</span> <span style="color: rgb(42,0,255);">Validation</span> <span style="color: rgb(42,0,255);">Test</span><br /><span style="color: rgb(0,0,0);">Bundle-SymbolicName</span><span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(42,0,255);">timezra.blog.uml_regex_validation.resources.tests;singleton:</span><span style="color: rgb(0,0,0);">=</span><span style="color: rgb(42,0,255);">true</span><br /><span style="color: rgb(0,0,0);">Bundle-Version</span><span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(42,0,255);">1.0.0.qualifier</span><br /><span style="color: rgb(0,0,0);">Bundle-Vendor</span><span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(42,0,255);">Timezra</span><br /><span style="color: rgb(0,0,0);">Fragment-Host</span><span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(42,0,255);">timezra.blog.uml_regex_validation.resources;bundle-version</span><span style="color: rgb(0,0,0);">=</span><span style="color: rgb(42,0,255);">"[1.0.0,2.0.0)"</span><br /><span style="color: rgb(0,0,0);">Bundle-RequiredExecutionEnvironment</span><span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(42,0,255);">J2SE-1.5</span><br /><span style="color: rgb(0,0,0);">Require-Bundle</span><span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(42,0,255);">org.junit4;bundle-version</span><span style="color: rgb(0,0,0);">=</span><span style="color: rgb(42,0,255);">"[4.5.0,5.0.0)",</span><br /><span style="color: rgb(0,0,0);"> org.eclipse.uml2.uml;bundle-version</span><span style="color: rgb(0,0,0);">=</span><span style="color: rgb(42,0,255);">"[3.0.0,4.0.0)",</span><br /><span style="color: rgb(0,0,0);"> org.eclipse.uml2.uml.resources;bundle-version</span><span style="color: rgb(0,0,0);">=</span><span style="color: rgb(42,0,255);">"[3.0.0,4.0.0)",</span><br /><span style="color: rgb(0,0,0);"> org.eclipse.uml2.uml.edit;bundle-version</span><span style="color: rgb(0,0,0);">=</span><span style="color: rgb(42,0,255);">"[3.0.0,4.0.0)"</span><br /></span><br /></div> <br /><br />The test suite will present a few challenges. For example, suppose we want to run our tests outside OSGi. We will need a way to simulate plug-in activation so that a singleton instance of our Activator is available. We will also need to initialize the resource set used to load the profile, and to redirect requests for platform resources to some other mechanism. Let's dig in our heels and get started by creating a new JUnit file, here called <em>timezra.blog.uml_regex.validation.resources.tests.ContactTest.java</em>:<br /><br />We can start the framework and activate the resources bundle before each test runs, and dispose of them after each test finishes:<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.uml_regex.validation.resources.tests;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Collections;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.osgi.launch.EquinoxFactory;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.After;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.Before;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.osgi.framework.BundleException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.osgi.framework.launch.Framework;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">timezra.blog.uml_regex_validation.resources.Activator;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">ContactTest</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Framework</span> <span style="color: rgb(0,0,0);">theFramework;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Activator</span> <span style="color: rgb(0,0,0);">thePlugin;</span><br /><br /> <span style="color: rgb(0,0,0);">@Before</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setUp()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">startTheFramework();</span><br /> <span style="color: rgb(0,0,0);">startThePlugin();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@After</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">tearDown()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">thePlugin.stop(theFramework.getBundleContext());</span><br /> <span style="color: rgb(0,0,0);">theFramework.stop();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">startThePlugin()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">thePlugin</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Activator();</span><br /> <span style="color: rgb(0,0,0);">thePlugin.start(theFramework.getBundleContext());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">startTheFramework()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">BundleException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">theFramework</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">EquinoxFactory().newFramework(Collections.emptyMap());</span><br /> <span style="color: rgb(0,0,0);">theFramework.init();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div> <br /><br />As well, we will <a href="http://wiki.eclipse.org/MDT-UML2-FAQ#What.27s_required_to_load_a_UML_.28.uml.29_resource_from_a_standalone_application.3F">initialize the resource set</a> during setup;<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,0,0);">....</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.io.IOException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.io.InputStream;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Map;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.emf.common.util.URI;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.emf.ecore.resource.ResourceSet;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.emf.ecore.resource.impl.URIHandlerImpl;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.uml2.uml.UMLPackage;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.uml2.uml.resource.UMLResource;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">ContactTest</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="color: rgb(0,0,0);">....</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">ResourceSet</span> <span style="color: rgb(0,0,0);">theResourceSet;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setUp()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">....</span><br /> <span style="color: rgb(0,0,0);">initializeTheResourceSet();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">....</span><br /> <br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">initializeTheResourceSet()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">theResourceSet</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">ResourceSetImpl();</span><br /> <span style="color: rgb(0,0,0);">theResourceSet.getPackageRegistry().put(UMLPackage.eNS_URI,</span> <span style="color: rgb(0,0,0);">UMLPackage.eINSTANCE);</span><br /> <span style="color: rgb(0,0,0);">theResourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(UMLResource.FILE_EXTENSION,</span><br /> <span style="color: rgb(0,0,0);">UMLResource.Factory.INSTANCE);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Map<URI,</span> <span style="color: rgb(0,0,0);">URI></span> <span style="color: rgb(0,0,0);">uriMap</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">theResourceSet.getURIConverter().getURIMap();</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">URI</span> <span style="color: rgb(0,0,0);">uri</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">URI.createURI(</span><span style="color: rgb(42,0,255);">"classpath:/"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">uriMap.put(URI.createURI(UMLResource.LIBRARIES_PATHMAP),</span> <span style="color: rgb(0,0,0);">uri.appendSegment(</span><span style="color: rgb(42,0,255);">"libraries"</span><span style="color: rgb(0,0,0);">).appendSegment(</span><span style="color: rgb(42,0,255);">""</span><span style="color: rgb(0,0,0);">));</span><br /> <span style="color: rgb(0,0,0);">uriMap.put(URI.createURI(UMLResource.METAMODELS_PATHMAP),</span> <span style="color: rgb(0,0,0);">uri.appendSegment(</span><span style="color: rgb(42,0,255);">"metamodels"</span><span style="color: rgb(0,0,0);">).appendSegment(</span><span style="color: rgb(42,0,255);">""</span><span style="color: rgb(0,0,0);">));</span><br /> <span style="color: rgb(0,0,0);">uriMap.put(URI.createURI(UMLResource.PROFILES_PATHMAP),</span> <span style="color: rgb(0,0,0);">uri.appendSegment(</span><span style="color: rgb(42,0,255);">"profiles"</span><span style="color: rgb(0,0,0);">).appendSegment(</span><span style="color: rgb(42,0,255);">""</span><span style="color: rgb(0,0,0);">));</span><br /><br /> <span style="color: rgb(0,0,0);">uriMap.put(thePlugin.createURIFor(</span><span style="color: rgb(42,0,255);">""</span><span style="color: rgb(0,0,0);">),</span> <span style="color: rgb(0,0,0);">uri);</span><br /><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div> <br /><br />We can use a simple mechanism that redirects platform resource and UML-specific URI requests to the classpath for loading the standard profiles as well as our custom profile:<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,0,0);">....</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.io.IOException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.io.InputStream;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.emf.ecore.resource.impl.URIHandlerImpl;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">ContactTest</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="color: rgb(0,0,0);">....</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">initializeTheResourceSet()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">....</span><br /> <span style="color: rgb(0,0,0);">theResourceSet.getURIConverter().getURIHandlers().add(0,</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">ClasspathURIHandler());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">ClasspathURIHandler</span> <span style="font-weight: bold; color: rgb(127,0,85);">extends</span> <span style="color: rgb(0,0,0);">URIHandlerImpl</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="color: rgb(0,0,0);">@Override</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">canHandle(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">URI</span> <span style="color: rgb(0,0,0);">uri)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(42,0,255);">"classpath"</span><span style="color: rgb(0,0,0);">.equals(uri.scheme());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Override</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">InputStream</span> <span style="color: rgb(0,0,0);">createInputStream(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">URI</span> <span style="color: rgb(0,0,0);">uri,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Map<?,</span> <span style="color: rgb(0,0,0);">?></span> <span style="color: rgb(0,0,0);">options)</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">IOException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">getClass().getResourceAsStream(uri.path());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br />We are now ready to write a few test cases. We can use the <em>org.eclipse.emf.ecore.util.Diagnostician</em> to perform validation for values set on the stereotype application itself or to check whether a value satisfies the stereotype attribute's restrictions. Our final class might look something like this:<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.uml_regex.validation.resources.tests;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">org.junit.Assert.assertEquals;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.io.IOException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.io.InputStream;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Collections;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Map;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.emf.common.util.Diagnostic;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.emf.common.util.URI;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.emf.ecore.EDataType;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.emf.ecore.EObject;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.emf.ecore.resource.Resource;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.emf.ecore.resource.ResourceSet;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.emf.ecore.resource.impl.URIHandlerImpl;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.emf.ecore.util.Diagnostician;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.osgi.launch.EquinoxFactory;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.uml2.uml.Actor;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.uml2.uml.Package;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.uml2.uml.Profile;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.uml2.uml.Stereotype;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.uml2.uml.UMLFactory;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.uml2.uml.UMLPackage;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.uml2.uml.resource.UMLResource;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.After;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.Before;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.Test;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.osgi.framework.BundleException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.osgi.framework.launch.Framework;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">timezra.blog.uml_regex_validation.resources.Activator;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">ContactTest</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">STEREOTYPE_QUALIFIED_NAME</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"ContactProfile::Contact"</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">PHONE_NUMBER_ATTRIBUTE</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"PhoneNumber"</span><span style="color: rgb(0,0,0);">;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">VALID_PHONE_NUMBER</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"555-555-5555"</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">INVALID_PHONE_NUMBER</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"555-555"</span><span style="color: rgb(0,0,0);">;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Framework</span> <span style="color: rgb(0,0,0);">theFramework;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Activator</span> <span style="color: rgb(0,0,0);">thePlugin;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">ResourceSet</span> <span style="color: rgb(0,0,0);">theResourceSet;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Profile</span> <span style="color: rgb(0,0,0);">theProfile;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Actor</span> <span style="color: rgb(0,0,0);">aContact;</span><br /><br /> <span style="color: rgb(0,0,0);">@Before</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setUp()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">startTheFramework();</span><br /> <span style="color: rgb(0,0,0);">startThePlugin();</span><br /> <span style="color: rgb(0,0,0);">initializeTheResourceSet();</span><br /> <span style="color: rgb(0,0,0);">loadTheProfile();</span><br /> <span style="color: rgb(0,0,0);">createAContact();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@After</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">tearDown()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">thePlugin.stop(theFramework.getBundleContext());</span><br /> <span style="color: rgb(0,0,0);">theFramework.stop();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">aValidPhoneNumberPassesTheDiagnostics()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">setThePhoneNumber(VALID_PHONE_NUMBER);</span><br /><br /> <span style="color: rgb(0,0,0);">assertEquals(Diagnostic.OK,</span> <span style="color: rgb(0,0,0);">diagnose(getTheStereotypeApplication()).getSeverity());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">anInvalidPhoneNumberFailsTheDiagnostics()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">setThePhoneNumber(INVALID_PHONE_NUMBER);</span><br /><br /> <span style="color: rgb(0,0,0);">assertEquals(Diagnostic.ERROR,</span> <span style="color: rgb(0,0,0);">diagnose(getTheStereotypeApplication()).getSeverity());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">theDataTypeRestrictsInvalidValues()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">assertEquals(Diagnostic.ERROR,</span> <span style="color: rgb(0,0,0);">diagnose(INVALID_PHONE_NUMBER).getSeverity());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">theDataTypeAllowsValidValues()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">assertEquals(Diagnostic.OK,</span> <span style="color: rgb(0,0,0);">diagnose(VALID_PHONE_NUMBER).getSeverity());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">EDataType</span> <span style="color: rgb(0,0,0);">getTheDataType()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">(EDataType)</span> <span style="color: rgb(0,0,0);">getTheStereotypeApplication().eClass().getEStructuralFeature(PHONE_NUMBER_ATTRIBUTE)</span><br /> <span style="color: rgb(0,0,0);">.getEType();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Diagnostic</span> <span style="color: rgb(0,0,0);">diagnose(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">thePhoneNumber)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">Diagnostician.INSTANCE.validate(getTheDataType(),</span> <span style="color: rgb(0,0,0);">thePhoneNumber);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Diagnostic</span> <span style="color: rgb(0,0,0);">diagnose(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">EObject</span> <span style="color: rgb(0,0,0);">theStereotypeApplication)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">Diagnostician.INSTANCE.validate(theStereotypeApplication);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setThePhoneNumber(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">thePhoneNumber)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">aContact.setValue(getTheStereotype(),</span> <span style="color: rgb(0,0,0);">PHONE_NUMBER_ATTRIBUTE,</span> <span style="color: rgb(0,0,0);">thePhoneNumber);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">EObject</span> <span style="color: rgb(0,0,0);">getTheStereotypeApplication()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">aContact.getStereotypeApplication(getTheStereotype());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Stereotype</span> <span style="color: rgb(0,0,0);">getTheStereotype()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">aContact.getAppliedStereotype(STEREOTYPE_QUALIFIED_NAME);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">createAContact()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Resource</span> <span style="color: rgb(0,0,0);">theResource</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">theResourceSet.createResource(URI.createURI(</span><span style="color: rgb(42,0,255);">"Contacts.uml"</span><span style="color: rgb(0,0,0);">));</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Package</span> <span style="color: rgb(0,0,0);">contacts</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">UMLFactory.eINSTANCE.createPackage();</span><br /> <span style="color: rgb(0,0,0);">theResource.getContents().add(contacts);</span><br /> <span style="color: rgb(0,0,0);">contacts.applyProfile(theProfile);</span><br /> <span style="color: rgb(0,0,0);">aContact</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">UMLFactory.eINSTANCE.createActor();</span><br /> <span style="color: rgb(0,0,0);">contacts.getPackagedElements().add(aContact);</span><br /> <span style="color: rgb(0,0,0);">aContact.applyStereotype(aContact.getApplicableStereotype(STEREOTYPE_QUALIFIED_NAME));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">loadTheProfile()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">theProfile</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">(Profile)</span> <span style="color: rgb(0,0,0);">thePlugin.loadProfile(theResourceSet).getContents().get(0);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">initializeTheResourceSet()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">theResourceSet</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">ResourceSetImpl();</span><br /> <span style="color: rgb(0,0,0);">theResourceSet.getPackageRegistry().put(UMLPackage.eNS_URI,</span> <span style="color: rgb(0,0,0);">UMLPackage.eINSTANCE);</span><br /> <span style="color: rgb(0,0,0);">theResourceSet.getResourceFactoryRegistry().getExtensionToFactoryMap().put(UMLResource.FILE_EXTENSION,</span><br /> <span style="color: rgb(0,0,0);">UMLResource.Factory.INSTANCE);</span><br /> <span style="color: rgb(0,0,0);">theResourceSet.getURIConverter().getURIHandlers().add(0,</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">ClasspathURIHandler());</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Map<URI,</span> <span style="color: rgb(0,0,0);">URI></span> <span style="color: rgb(0,0,0);">uriMap</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">theResourceSet.getURIConverter().getURIMap();</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">URI</span> <span style="color: rgb(0,0,0);">uri</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">URI.createURI(</span><span style="color: rgb(42,0,255);">"classpath:/"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">uriMap.put(URI.createURI(UMLResource.LIBRARIES_PATHMAP),</span> <span style="color: rgb(0,0,0);">uri.appendSegment(</span><span style="color: rgb(42,0,255);">"libraries"</span><span style="color: rgb(0,0,0);">).appendSegment(</span><span style="color: rgb(42,0,255);">""</span><span style="color: rgb(0,0,0);">));</span><br /> <span style="color: rgb(0,0,0);">uriMap.put(URI.createURI(UMLResource.METAMODELS_PATHMAP),</span> <span style="color: rgb(0,0,0);">uri.appendSegment(</span><span style="color: rgb(42,0,255);">"metamodels"</span><span style="color: rgb(0,0,0);">).appendSegment(</span><span style="color: rgb(42,0,255);">""</span><span style="color: rgb(0,0,0);">));</span><br /> <span style="color: rgb(0,0,0);">uriMap.put(URI.createURI(UMLResource.PROFILES_PATHMAP),</span> <span style="color: rgb(0,0,0);">uri.appendSegment(</span><span style="color: rgb(42,0,255);">"profiles"</span><span style="color: rgb(0,0,0);">).appendSegment(</span><span style="color: rgb(42,0,255);">""</span><span style="color: rgb(0,0,0);">));</span><br /><br /> <span style="color: rgb(0,0,0);">uriMap.put(thePlugin.createURIFor(</span><span style="color: rgb(42,0,255);">""</span><span style="color: rgb(0,0,0);">),</span> <span style="color: rgb(0,0,0);">uri);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">startThePlugin()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">thePlugin</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Activator();</span><br /> <span style="color: rgb(0,0,0);">thePlugin.start(theFramework.getBundleContext());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">startTheFramework()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">BundleException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">theFramework</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">EquinoxFactory().newFramework(Collections.emptyMap());</span><br /> <span style="color: rgb(0,0,0);">theFramework.init();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">ClasspathURIHandler</span> <span style="font-weight: bold; color: rgb(127,0,85);">extends</span> <span style="color: rgb(0,0,0);">URIHandlerImpl</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="color: rgb(0,0,0);">@Override</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">canHandle(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">URI</span> <span style="color: rgb(0,0,0);">uri)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(42,0,255);">"classpath"</span><span style="color: rgb(0,0,0);">.equals(uri.scheme());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Override</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">InputStream</span> <span style="color: rgb(0,0,0);">createInputStream(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">URI</span> <span style="color: rgb(0,0,0);">uri,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Map<?,</span> <span style="color: rgb(0,0,0);">?></span> <span style="color: rgb(0,0,0);">options)</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">IOException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">getClass().getResourceAsStream(uri.path());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div> <br /><br /><h4>Test With Tycho:</h4><br />Suppose we want to automate our plug-in build and unit-tests. There are <a href="http://wiki.eclipse.org/PDE/Incubator/b3/Proposal">a</a> <a href="http://www.eclipse.org/buckminster/">few</a> <a href="http://wiki.eclipse.org/Common_Build_Infrastructure">different</a> <a href="http://wiki.eclipse.org/index.php/PDEBuild">options</a> in the Eclipse eco-system, but my personal preference lately has been <a href="http://tycho.sonatype.org/">tycho</a>. Currently, I am using tycho-0.8.0 and Maven 3-alpha-7 with Eclipse-3.5.2. Be aware that the latest version as of this first posting requires Maven 3-beta-1 and Eclipse-3.6-M7. My environment is configured according to <a href="http://mattiasholmqvist.se/2010/02/building-with-tycho-part-1-osgi-bundles/">the instructions</a> provided by Mattias Holmqvist.<br /><br />For our particular plugins, we can generate the poms for the functional resources plug-in, for the test fragment and for the parent <em>plugins</em> directory.<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /> export M2_HOME=/path/to/apache-maven-3.0-alpha-7<br /> export MAVEN_OPTS="-Xmx512m"<br /> export TYCHO_TARGET_PLATFORM=/path/to/eclipse_3.5.2<br /> cd /path/to/timezra.blog.uml_regex_validation.resources<br /> mvn org.sonatype.tycho:maven-tycho-plugin:generate-poms -DgroupId=timezra.blog -Dtycho.targetPlatform=$TYCHO_TARGET_PLATFORM<br /> cd /path/to/timezra.blog.uml_regex_validation.resources.test<br /> mvn org.sonatype.tycho:maven-tycho-plugin:generate-poms -DgroupId=timezra.blog -Dtycho.targetPlatform=$TYCHO_TARGET_PLATFORM<br /> cd ..<br /> mvn org.sonatype.tycho:maven-tycho-plugin:generate-poms -DgroupId=timezra.blog -Dtycho.targetPlatform=$TYCHO_TARGET_PLATFORM<br /></div><br /><br />We can modify the pom generated in our fragment to include the following section, which will <a href="http://timezra.blogspot.com/2010/05/tycho-tests-without-osgi.html">enable tycho to run microtests outside OSGi</a>:<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(0,0,0);">.</span>...<span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">packaging</span><span style="color: rgb(0,128,128);">></span>eclipse-test-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">packaging</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.apache.maven.plugins<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>maven-surefire-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">testClassesDirectory</span><span style="color: rgb(0,128,128);">></span>${project.build.outputDirectory}<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">testClassesDirectory</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>junit<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>junit<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>4.7<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br />Finally we can run our unit-tests from the parent <em>plugins</em> directory:<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /> mvn clean test -Dtycho.targetPlatform=$TYCHO_TARGET_PLATFORM<br /></div><br /><br /><h4>Conclusion:</h4><br />The primary purpose of this tutorial has been to present a way to test Stereotype attributes that use UML Data Types constrained by regular expressions. Along the way, we have also developed techniques for simulating bundle activation outside OSGi, for loading platform plugin resources and resources registered through Eclipse extensions without Eclipse running, and for running microtests with Maven via tycho.Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com0tag:blogger.com,1999:blog-106449775438946661.post-66313282138974602332010-05-20T23:04:00.000-07:002010-05-21T08:46:04.232-07:00Tycho Tests Without OSGi<h4>Goal:</h4><br />The <a href="http://tycho.sonatype.org/">tycho</a> project brings the power and convenience of Maven to Eclipse plug-in development. Having automated the builds for and developed (test-driven) two commercial Eclipse plug-in and RCP applications, I have always found PDE build to be the soft underbelly of the Eclipse armadillo. But I muddled my way through and over time built comprehensive suites of both JUnit microtests and Plug-in integration tests. While tycho's facility for integration tests is particularly impressive, the vast majority of my suites do not need the OSGi runtime, and some, in fact, would break when run as integration tests. In addition, some Eclipse plug-ins are implemented with the intention that they will be used outside Eclipse (EMF, for example) as well as in, and I would imagine that tests for these types of plug-ins would need to run as plain ol' JUnits for certain scenarios. The goal of this entry is to present one possibility for running microtests under tycho without OSGi.<br /><br /><h4>Generate Default Poms:</h4><br />First, we will need to install tycho. I primarily followed <a href="http://mattiasholmqvist.se/2010/02/building-with-tycho-part-1-osgi-bundles/">Mattias Holmqvist's</a> instructions, along with <a href="https://docs.sonatype.org/display/TYCHO/BuildingTycho">a</a> <a href="http://divby0.blogspot.com/2010/03/im-in-love-with-tycho-08-and-maven-3.html">few</a> <a href="http://www.sonatype.com/people/2008/11/building-eclipse-plugins-with-maven-tycho/">others</a>, to install <a href="http://maven.apache.org/download.html">Maven 3 (alpha 7)</a>, to build <a href="http://github.com/sonatype/sonatype-tycho">tycho from source</a>, and to <a href="http://www.sonatype.com/people/2008/11/building-eclipse-plugins-with-maven-tycho/">generate poms</a> from my existing plug-ins and test fragments.<br />After generating a parent pom in the plugins directory above the individual plug-in and test fragment projects, running integration tests is simple:<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /> mvn integration-test -Dtycho.targetPlatform=$TYCHO_TARGET_PLATFORM<br /></div><br /><br /><h4>Run The Microtests:</h4><br />Now that we have tycho building our plug-ins and running integration tests, we can modify the generated poms in test fragments which do not need the OSGi runtime. Fortunately, this is only a matter of configuring the surefire plug-in (and adding a JUnit 4 dependency if necessary):<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(0,0,0);">.</span>...<span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">packaging</span><span style="color: rgb(0,128,128);">></span>eclipse-test-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">packaging</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.apache.maven.plugins<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>maven-surefire-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">testClassesDirectory</span><span style="color: rgb(0,128,128);">></span>${project.build.outputDirectory}<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">testClassesDirectory</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>junit<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>junit<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>4.7<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br />From the plugins directory, running microtests is simple:<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /> mvn test -Dtycho.targetPlatform=$TYCHO_TARGET_PLATFORM<br /></div><br /><br /><h4>Conclusion:</h4><br />With the ability to run JUnit tests for Eclipse plug-ins without OSGi, we are now able to migrate existing projects incrementally to tycho. Hopefully, others who are facing similar problems will find this tutorial useful.Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com5tag:blogger.com,1999:blog-106449775438946661.post-82966350759939987732010-05-11T23:21:00.000-07:002010-05-11T23:40:00.020-07:00A RegEx To Validate URIs<h4>Goal:</h4><br />To test-drive the creation of a regular expression to validate URIs based on <a href="http://www.ietf.org/rfc/rfc2396.txt">the BNF in Appendix A of RFC 2396</a>.<br /><br /><h4>Motivation:</h4><br />Other <a href="http://lists.xml.org/archives/xml-dev/200108/msg00891.html">publicly available regular expressions</a> were insufficient for my needs. After meticulously starting to implement my own regex by proceeding to translate every line of the <a href="http://www.ietf.org/rfc/rfc2396.txt">BNF grammar</a>, I realized this mode of working would be error-prone, and I needed an automated way to verify the correctness of the regular expression.<br /><br /><h4>The Test:</h4><br />The test cases can follow a systematic template: <ul><li>we have a regular expression that we want to validate;</li><li>we need to verify that the regular expression accepts values that conform to the BNF grammar;</li><li>we also need to demonstrate that the regular expression does not accept values that do not conform to the BNF grammar.</li></ul><br />For the purposes of this tutorial, we can plan on validating the URI parts that correspond to the components described in <a href="http://www.ietf.org/rfc/rfc2396.txt">Appendix B of RFC 2396</a>, i.e., <em>scheme</em>, <em>authority</em>, <em>path</em>, <em>query</em> and <em>fragment</em>, as well as the entirety of the <em>URI-reference</em>.<br />In order to demonstrate that the regex accepts values that conform to the BNF grammar, we can use a package like <a href="http://code.google.com/p/xeger/">Xeger</a> to generate random values based on our regular expression, and we will verify with a Java translation of the BNF that these generated values are indeed valid.<br />To verify that the regular expression does not accept values that do not conform to the BNF, we can again use <a href="http://code.google.com/p/xeger/">Xeger</a>, but we will <em>negate</em> the regular expression and verify that the generated values are not valid using our Java translation of the BNF.<br /><br />Now that we have a plan, we can set up a new project by downloading <a href="http://xeger.googlecode.com/files/xeger-1.0-SNAPSHOT.jar">Xeger</a> and the engine that drives it, <a href="http://www.brics.dk/~amoeller/automaton/automaton.jar">automaton</a>.<br /><a href="http://www.brics.dk/~amoeller/automaton/">Automaton</a> can be installed directly into our local maven repository<br /><div style="overflow:auto;width:60%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /> mvn install:install-file -DgroupId=dk.brics -DartifactId=automaton -Dversion=1.11 -Dpackaging=jar -Dfile=/path/to/automaton.jar<br /></div><br /><a href="http://code.google.com/p/xeger/">Xeger</a> is already a maven project so we can either install the <a href="http://xeger.googlecode.com/files/xeger-1.0-SNAPSHOT.jar">archive</a> directly, or install the module from <a href="http://code.google.com/p/xeger/source/checkout">source</a>.<br /><br />An example <em>pom.xml</em> for our project might look something like this:<br /><div style="overflow:auto;height:500px;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0"</span> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span><br /> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span>4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>timezra<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>uri_regex<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>0.0.1-SNAPSHOT<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span>uri_regex<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.apache.maven.plugins<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>maven-compiler-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">source</span><span style="color: rgb(0,128,128);">></span>1.5<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">source</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">target</span><span style="color: rgb(0,128,128);">></span>1.5<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">target</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>nl.flotsam<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>xeger<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.0-SNAPSHOT<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>junit<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>junit<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>4.7<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>com.google.collections<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>google-collections<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><br />We are now ready to create the initial implementation for the test class, here called <em>timezra.blog.uri_regex.URIRegExTest.java</em>.<br />When we build our regular expressions from the bottom of the BNF grammar upwards, the first entire URI component that we encounter is the regex for <em>fragments</em>, so our first test case should validate that <em>fragments</em> work correctly.<br /><div style="overflow:auto;height:750px;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.uri_regex;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">java.util.Arrays.asList;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">org.junit.Assert.assertFalse;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">org.junit.Assert.assertTrue;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.ArrayList;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Collection;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.HashSet;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">nl.flotsam.xeger.Xeger;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.Test;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">com.google.common.base.Function;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">URIRegExTest</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">FRAGMENT_REGEX</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\);/\\?:\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*"</span><span style="color: rgb(0,0,0);">;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">NUMBER_OF_TESTS</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">100000;</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">theFragmentRegExIsNecessaryAndSufficient()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">verifyTheRegEx(FRAGMENT_REGEX,</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Function<String,</span> <span style="color: rgb(0,0,0);">Boolean>()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Boolean</span> <span style="color: rgb(0,0,0);">apply(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">s)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">fragment(s);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">});</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">verifyTheRegEx(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">pattern,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Function<String,</span> <span style="color: rgb(0,0,0);">Boolean></span> <span style="color: rgb(0,0,0);">f)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Xeger</span> <span style="color: rgb(0,0,0);">generator</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Xeger(pattern);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">0;</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">NUMBER_OF_TESTS;</span> <span style="color: rgb(0,0,0);">i++)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">generated</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">generator.generate();</span><br /> <span style="color: rgb(0,0,0);">assertTrue(String.format(</span><span style="color: rgb(42,0,255);">"Verifying the value '%s'."</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">generated),</span> <span style="color: rgb(0,0,0);">f.apply(generated));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Xeger</span> <span style="color: rgb(0,0,0);">negativeGenerator</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Xeger(negate(pattern));</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">0;</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">NUMBER_OF_TESTS;</span> <span style="color: rgb(0,0,0);">i++)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">generated</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">negativeGenerator.generate();</span><br /> <span style="color: rgb(0,0,0);">assertFalse(String.format(</span><span style="color: rgb(42,0,255);">"Verifying the negative '%s'."</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">generated),</span> <span style="color: rgb(0,0,0);">f.apply(generated));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Character></span> <span style="color: rgb(0,0,0);">mark;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Character></span> <span style="color: rgb(0,0,0);">reserved;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">mark</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">HashSet<Character>(asList(</span><span style="color: rgb(42,0,255);">'-'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'_'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'.'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'!'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'~'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'*'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'\''</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'('</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">')'</span><span style="color: rgb(0,0,0);">));</span><br /> <span style="color: rgb(0,0,0);">reserved</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">HashSet<Character>(asList(</span><span style="color: rgb(42,0,255);">';'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'/'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'?'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">':'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'@'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'&'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'='</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'+'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'$'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">','</span><span style="color: rgb(0,0,0);">));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">fragment(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">s)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">fragment(codePoints(s));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">fragment(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">uric_star(codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">uric_star(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">anyNumberOfUnreservedOrEscapedOrSpecial(reserved,</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">unreserved(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">codePoint)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">alphanum(codePoint)</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">mark(codePoint);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">mark(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">codePoint)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">contains(mark,</span> <span style="color: rgb(0,0,0);">codePoint);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">escaped(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">codePoints.length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">3</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">isChar(codePoints[0])</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">codePoints[0]</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(42,0,255);">'%'</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">hex(codePoints[1])</span><br /> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">hex(codePoints[2]);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">hex(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">codePoint)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(digit(codePoint))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(alpha(codePoint))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">letter</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">Character.toLowerCase(codePoint);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(42,0,255);">'a'</span> <span style="color: rgb(0,0,0);"><=</span> <span style="color: rgb(0,0,0);">letter</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">letter</span> <span style="color: rgb(0,0,0);"><=</span> <span style="color: rgb(42,0,255);">'f'</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">alphanum(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">codePoint)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">digit(codePoint)</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">alpha(codePoint);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">digit(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">codePoint)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(isChar(codePoint))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">char</span> <span style="color: rgb(0,0,0);">c</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">char</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">codePoint;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(42,0,255);">'0'</span> <span style="color: rgb(0,0,0);"><=</span> <span style="color: rgb(0,0,0);">c</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">c</span> <span style="color: rgb(0,0,0);"><=</span> <span style="color: rgb(42,0,255);">'9'</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">alpha(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">codePoint)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(isChar(codePoint))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">char</span> <span style="color: rgb(0,0,0);">c</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">char</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">codePoint;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(42,0,255);">'a'</span> <span style="color: rgb(0,0,0);"><=</span> <span style="color: rgb(0,0,0);">c</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">c</span> <span style="color: rgb(0,0,0);"><=</span> <span style="color: rgb(42,0,255);">'z'</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(42,0,255);">'A'</span> <span style="color: rgb(0,0,0);"><=</span> <span style="color: rgb(0,0,0);">c</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">c</span> <span style="color: rgb(0,0,0);"><=</span> <span style="color: rgb(42,0,255);">'Z'</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">anyNumberOfUnreservedOrEscapedOrSpecial(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Character></span> <span style="color: rgb(0,0,0);">special,</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">eachSymbol(</span><span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Function<Integer[],</span> <span style="color: rgb(0,0,0);">Boolean>()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Boolean</span> <span style="color: rgb(0,0,0);">apply(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">ps)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">isUnreservedOrEscapedOrSpecial(special,</span> <span style="color: rgb(0,0,0);">ps);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">},</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">isUnreservedOrEscapedOrSpecial(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Character></span> <span style="color: rgb(0,0,0);">special,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(codePoints.length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">1)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">unreserved(codePoints[0])</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">contains(special,</span> <span style="color: rgb(0,0,0);">codePoints[0]);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">escaped(codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">contains(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Character></span> <span style="color: rgb(0,0,0);">cs,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">codePoint)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">isChar(codePoint)</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">cs.contains(Character.valueOf((</span><span style="font-weight: bold; color: rgb(127,0,85);">char</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">codePoint));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">eachSymbol(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Function<Integer[],</span> <span style="color: rgb(0,0,0);">Boolean></span> <span style="color: rgb(0,0,0);">f,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">0;</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">codePoints.length;)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">next</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">nextSymbol(i,</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(!f.apply(next))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">+=</span> <span style="color: rgb(0,0,0);">next.length;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">nextSymbol(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">i,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(codePoints[i]</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(42,0,255);">'%'</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(i</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">2</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">codePoints.length)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(0,0,0);">codePoints[i],</span> <span style="color: rgb(0,0,0);">codePoints[i</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">1],</span> <span style="color: rgb(0,0,0);">codePoints[i</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">2]</span> <span style="color: rgb(0,0,0);">};</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(0,0,0);">codePoints[i]</span> <span style="color: rgb(0,0,0);">};</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">isChar(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">codePoint)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">Character.charCount(codePoint)</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">1;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">negate(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">regEx)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">String.format(</span><span style="color: rgb(42,0,255);">"~(%s)"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">regEx);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">codePoints(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">s)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Integer></span> <span style="color: rgb(0,0,0);">codePoints</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">ArrayList<Integer>();</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">s</span> <span style="color: rgb(0,0,0);">==</span> <span style="font-weight: bold; color: rgb(127,0,85);">null</span> <span style="color: rgb(0,0,0);">?</span> <span style="color: rgb(0,0,0);">0</span> <span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(0,0,0);">s.length();</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">0;</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">length;)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">codepoint</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">s.codePointAt(i);</span><br /> <span style="color: rgb(0,0,0);">codePoints.add(codepoint);</span><br /> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">+=</span> <span style="color: rgb(0,0,0);">Character.charCount(codepoint);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">codePoints.toArray(</span><span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Integer[codePoints.size()]);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br />As astute as you are, you might be asking why I have chosen to translate the BNF into Java to verify the correctness of the URI components, especially when there are already at least 3 perfectly good, validating URI implementations in Java: <em>java.net.URI</em>, <em>org.eclipse.emf.common.util.URI</em> and <em>org.apache.commons.httpclient.URI</em>, any of which could easily be incorporated into the project with just a couple of lines of Maven configuration, or no extra configuration at all. Originally, I had gone down this route, and to my surprise, none of these implementations suited my needs:<ul><li><em>java.net.URI</em> does not allow certain RFC 2396 URIs, such as "//"</li><li><em>org.eclipse.emf.common.util.URI</em> is not strict enough (just look at the commented-out implementations of the validation methods)</li><li><em>org.apache.commons.httpclient.URI</em> is character-based, not code-point-based, so I ran into a number of false positive results, particularly with Asian characters.</li></ul><br />I strongly encourage you to setup a simple test yourself to double-check my work or to delve deeper into the implementation details to see how URIs are handled by the 3 different libraries.<br /><br />Now that the test case is ready, we can incrementally proceed with our translation and verify our results at a few select checkpoints along the way.<br /><br /><h4>Translating the BNF:</h4><br /><br />In most cases, components at the top of the BNF grammar are built from combinations of components that appeared earlier. For clarity, the BNF grammar has been reversed, so that the incremental translation can be read from the top of the page to the bottom. The resulting <em>URI-reference</em> regex at the bottom could surely be optimized or shortened since there is significant repetition, but for now, I am primarily concerned with its correctness, not with its size or speed. <br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-style: italic; color: rgb(42,0,255);">digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"</span><br /><span style="color: rgb(63,127,127);">digit = </span>[0-9]<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">upalpha = "A" | "B" | "C" | "D" | "E" | "F" | "G" | "H" | "I" | "J" | "K" | "L" | "M" | "N" | "O" | "P" | "Q" | "R" | "S" | "T" | "U" | "V" | "W" | "X" | "Y" | "Z"</span><br /><span style="color: rgb(63,127,127);">upalpha = </span>[A-Z]<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">lowalpha = "a" | "b" | "c" | "d" | "e" | "f" | "g" | "h" | "i" | "j" | "k" | "l" | "m" | "n" | "o" | "p" | "q" | "r" | "s" | "t" | "u" | "v" | "w" | "x" | "y" | "z"</span><br /><span style="color: rgb(63,127,127);">lowalpha = </span>[a-z]<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">alpha = lowalpha | upalpha</span><br /><span style="color: rgb(63,127,127);">alpha = </span>[a-zA-Z]<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">alphanum = alpha | digit</span><br /><span style="color: rgb(63,127,127);">alphanum = </span>[a-zA-Z0-9]<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">hex = digit | "A" | "B" | "C" | "D" | "E" | "F" | "a" | "b" | "c" | "d" | "e" | "f"</span><br /><span style="color: rgb(63,127,127);">hex = </span>[a-fA-F0-9]<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">escaped = "%" hex hex</span><br /><span style="color: rgb(63,127,127);">escaped = </span>%[a-fA-F0-9]{2}<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">mark = "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")"</span><br /><span style="color: rgb(63,127,127);">mark = </span>[\-_\.!\~\*'\(\)]<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">unreserved = alphanum | mark</span><br /><span style="color: rgb(63,127,127);">unreserved = </span>[a-zA-Z0-9\-_\.!\~\*'\(\)]<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">reserved = ";" | "/" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","</span><br /><span style="color: rgb(63,127,127);">reserved = </span>[;/\?:\@\&=\+$,]<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">uric = reserved | unreserved | escaped</span><br /><span style="color: rgb(63,127,127);">uric = </span>[a-zA-Z0-9\-_\.!\~\*'\(\);/\?:\@\&=\+$,]|(%[a-fA-F0-9]{2})<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">fragment = *uric</span><br /><span style="color: rgb(63,127,127);">fragment = </span>([a-zA-Z0-9\-_\.!\~\*'\(\);/\?:\@\&=\+$,]|(%[a-fA-F0-9]{2}))*<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">query = *uric</span><br /><span style="color: rgb(63,127,127);">query = </span>([a-zA-Z0-9\-_\.!\~\*'\(\);/\?:\@\&=\+$,]|(%[a-fA-F0-9]{2}))*<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">pchar = unreserved | escaped | ":" | "@" | "&" | "=" | "+" | "$" | ","</span><br /><span style="color: rgb(63,127,127);">pchar = </span>[a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2})<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">param = *pchar</span><br /><span style="color: rgb(63,127,127);">param = </span>([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">segment = *pchar *( ";" param )</span><br /><span style="color: rgb(63,127,127);">segment = </span>([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">path_segments = segment *( "/" segment )</span><br /><span style="color: rgb(63,127,127);">path_segments = </span>(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*))*<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">path = [ abs_path | opaque_part ]</span><br /><span style="color: rgb(63,127,127);">path = </span>((/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*))*)|(([a-zA-Z0-9\-_\.!\~\*'\(\);\?:\@\&=\+$,]|(%[a-fA-F0-9]{2}))([a-zA-Z0-9\-_\.!\~\*'\(\);/\?:\@\&=\+$,]|(%[a-fA-F0-9]{2}))*))?<br /> <br /><span style="font-style: italic; color: rgb(42,0,255);">port = *digit</span><br /><span style="color: rgb(63,127,127);">port = </span>[0-9]*<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">IPv4address = 1*digit "." 1*digit "." 1*digit "." 1*digit</span><br /><span style="color: rgb(63,127,127);">IPv4address = </span>[0-9]+((\.[0-9]+){3})<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">toplabel = alpha | alpha *( alphanum | "-" ) alphanum</span><br /><span style="color: rgb(63,127,127);">toplabel = </span>[a-zA-Z](([a-zA-Z0-9\-])*[a-zA-Z0-9])?<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">domainlabel = alphanum | alphanum *( alphanum | "-" ) alphanum</span><br /><span style="color: rgb(63,127,127);">domainlabel = </span>[a-zA-Z0-9](([a-zA-Z0-9\-])*[a-zA-Z0-9])?<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">hostname = *( domainlabel "." ) toplabel [ "." ]</span><br /><span style="color: rgb(63,127,127);">hostname = </span>(([a-zA-Z0-9](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)\.)*([a-zA-Z](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)(\.)?<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">host = hostname | IPv4address</span><br /><span style="color: rgb(63,127,127);">host = </span>((([a-zA-Z0-9](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)\.)*([a-zA-Z](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)(\.)?)|([0-9]+((\.[0-9]+){3}))<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">hostport = host [ ":" port ]</span><br /><span style="color: rgb(63,127,127);">hostport = </span>(((([a-zA-Z0-9](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)\.)*([a-zA-Z](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)(\.)?)|([0-9]+((\.[0-9]+){3})))(:[0-9]*)?<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">userinfo = *( unreserved | escaped | ";" | ":" | "&" | "=" | "+" | "$" | "," )</span><br /><span style="color: rgb(63,127,127);">userinfo = </span>([a-zA-Z0-9\-_\.!\~\*'\(\);:\&=\+$,]|(%[a-fA-F0-9]{2}))*<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">server = [ [ userinfo "@" ] hostport ]</span><br /><span style="color: rgb(63,127,127);">server = </span>(((([a-zA-Z0-9\-_\.!\~\*'\(\);:\&=\+$,]|(%[a-fA-F0-9]{2}))*)\@)?((((([a-zA-Z0-9](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)\.)*([a-zA-Z](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)(\.)?)|([0-9]+((\.[0-9]+){3})))(:[0-9]*)?))?<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">reg_name = 1*( unreserved | escaped | "$" | "," | ";" | ":" | "@" | "&" | "=" | "+" )</span><br /><span style="color: rgb(63,127,127);">reg_name = </span>([a-zA-Z0-9\-_\.!\~\*'\(\)$,;:\@\&=\+]|(%[a-fA-F0-9]{2}))+<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">authority = server | reg_name</span><br /><span style="color: rgb(63,127,127);">authority = </span>(((([a-zA-Z0-9\-_\.!\~\*'\(\);:\&=\+$,]|(%[a-fA-F0-9]{2}))*)\@)?((((([a-zA-Z0-9](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)\.)*([a-zA-Z](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)(\.)?)|([0-9]+((\.[0-9]+){3})))(:[0-9]*)?))?|([a-zA-Z0-9\-_\.!\~\*'\(\)$,;:\@\&=\+]|(%[a-fA-F0-9]{2}))+<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">scheme = alpha *( alpha | digit | "+" | "-" | "." )</span><br /><span style="color: rgb(63,127,127);">scheme = </span>[a-zA-Z][a-zA-Z0-9\+\-\.]*<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">rel_segment = 1*( unreserved | escaped | ";" | "@" | "&" | "=" | "+" | "$" | "," )</span><br /><span style="color: rgb(63,127,127);">rel_segment = </span>([a-zA-Z0-9\-_\.!\~\*'\(\);\@\&=\+$,]|(%[a-fA-F0-9]{2}))+<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">rel_path = rel_segment [ abs_path ]</span><br /><span style="color: rgb(63,127,127);">rel_path = </span>([a-zA-Z0-9\-_\.!\~\*'\(\);\@\&=\+$,]|(%[a-fA-F0-9]{2}))+(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*))*)?<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">abs_path = "/" path_segments</span><br /><span style="color: rgb(63,127,127);">abs_path = </span>/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*))*<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">net_path = "//" authority [ abs_path ]</span><br /><span style="color: rgb(63,127,127);">net_path = </span>//((((([a-zA-Z0-9\-_\.!\~\*'\(\);:\&=\+$,]|(%[a-fA-F0-9]{2}))*)\@)?((((([a-zA-Z0-9](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)\.)*([a-zA-Z](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)(\.)?)|([0-9]+((\.[0-9]+){3})))(:[0-9]*)?))?|([a-zA-Z0-9\-_\.!\~\*'\(\)$,;:\@\&=\+]|(%[a-fA-F0-9]{2}))+)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*))*)?<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">uric_no_slash = unreserved | escaped | ";" | "?" | ":" | "@" | "&" | "=" | "+" | "$" | ","</span><br /><span style="color: rgb(63,127,127);">uric_no_slash = </span>[a-zA-Z0-9\-_\.!\~\*'\(\);\?:\@\&=\+$,]|(%[a-fA-F0-9]{2})<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">opaque_part = uric_no_slash *uric</span><br /><span style="color: rgb(63,127,127);">opaque_part = </span>([a-zA-Z0-9\-_\.!\~\*'\(\);\?:\@\&=\+$,]|(%[a-fA-F0-9]{2}))([a-zA-Z0-9\-_\.!\~\*'\(\);/\?:\@\&=\+$,]|(%[a-fA-F0-9]{2}))*<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">hier_part = ( net_path | abs_path ) [ "?" query ]</span><br /><span style="color: rgb(63,127,127);">hier_part = </span>((//((((([a-zA-Z0-9\-_\.!\~\*'\(\);:\&=\+$,]|(%[a-fA-F0-9]{2}))*)\@)?((((([a-zA-Z0-9](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)\.)*([a-zA-Z](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)(\.)?)|([0-9]+((\.[0-9]+){3})))(:[0-9]*)?))?|([a-zA-Z0-9\-_\.!\~\*'\(\)$,;:\@\&=\+]|(%[a-fA-F0-9]{2}))+)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*))*)?)|(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*))*))(\?([a-zA-Z0-9\-_\.!\~\*'\(\);/\?:\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)?<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">relativeURI = ( net_path | abs_path | rel_path ) [ "?" query ]</span><br /><span style="color: rgb(63,127,127);">relativeURI = </span>((//((((([a-zA-Z0-9\-_\.!\~\*'\(\);:\&=\+$,]|(%[a-fA-F0-9]{2}))*)\@)?((((([a-zA-Z0-9](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)\.)*([a-zA-Z](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)(\.)?)|([0-9]+((\.[0-9]+){3})))(:[0-9]*)?))?|([a-zA-Z0-9\-_\.!\~\*'\(\)$,;:\@\&=\+]|(%[a-fA-F0-9]{2}))+)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*))*)?)|(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*))*)|(([a-zA-Z0-9\-_\.!\~\*'\(\);\@\&=\+$,]|(%[a-fA-F0-9]{2}))+(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*))*)?))(\?([a-zA-Z0-9\-_\.!\~\*'\(\);/\?:\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)?<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">absoluteURI = scheme ":" ( hier_part | opaque_part )</span><br /><span style="color: rgb(63,127,127);">absoluteURI = </span>[a-zA-Z][a-zA-Z0-9\+\-\.]*:((((//((((([a-zA-Z0-9\-_\.!\~\*'\(\);:\&=\+$,]|(%[a-fA-F0-9]{2}))*)\@)?((((([a-zA-Z0-9](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)\.)*([a-zA-Z](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)(\.)?)|([0-9]+((\.[0-9]+){3})))(:[0-9]*)?))?|([a-zA-Z0-9\-_\.!\~\*'\(\)$,;:\@\&=\+]|(%[a-fA-F0-9]{2}))+)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*))*)?)|(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*))*))(\?([a-zA-Z0-9\-_\.!\~\*'\(\);/\?:\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)?)|(([a-zA-Z0-9\-_\.!\~\*'\(\);\?:\@\&=\+$,]|(%[a-fA-F0-9]{2}))([a-zA-Z0-9\-_\.!\~\*'\(\);/\?:\@\&=\+$,]|(%[a-fA-F0-9]{2}))*))<br /><br /><span style="font-style: italic; color: rgb(42,0,255);">URI-reference = [ absoluteURI | relativeURI ] [ "#" fragment ]</span><br /><span style="color: rgb(63,127,127);">URI-reference = </span>(([a-zA-Z][a-zA-Z0-9\+\-\.]*:((((//((((([a-zA-Z0-9\-_\.!\~\*'\(\);:\&=\+$,]|(%[a-fA-F0-9]{2}))*)\@)?((((([a-zA-Z0-9](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)\.)*([a-zA-Z](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)(\.)?)|([0-9]+((\.[0-9]+){3})))(:[0-9]*)?))?|([a-zA-Z0-9\-_\.!\~\*'\(\)$,;:\@\&=\+]|(%[a-fA-F0-9]{2}))+)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*))*)?)|(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*))*))(\?([a-zA-Z0-9\-_\.!\~\*'\(\);/\?:\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)?)|(([a-zA-Z0-9\-_\.!\~\*'\(\);\?:\@\&=\+$,]|(%[a-fA-F0-9]{2}))([a-zA-Z0-9\-_\.!\~\*'\(\);/\?:\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)))|(((//((((([a-zA-Z0-9\-_\.!\~\*'\(\);:\&=\+$,]|(%[a-fA-F0-9]{2}))*)\@)?((((([a-zA-Z0-9](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)\.)*([a-zA-Z](([a-zA-Z0-9\-])*[a-zA-Z0-9])?)(\.)?)|([0-9]+((\.[0-9]+){3})))(:[0-9]*)?))?|([a-zA-Z0-9\-_\.!\~\*'\(\)$,;:\@\&=\+]|(%[a-fA-F0-9]{2}))+)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*))*)?)|(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*))*)|(([a-zA-Z0-9\-_\.!\~\*'\(\);\@\&=\+$,]|(%[a-fA-F0-9]{2}))+(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\-_\.!\~\*'\(\):\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)*))*)?))(\?([a-zA-Z0-9\-_\.!\~\*'\(\);/\?:\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)?))?(\#([a-zA-Z0-9\-_\.!\~\*'\(\);/\?:\@\&=\+$,]|(%[a-fA-F0-9]{2}))*)?</span><br /></div><br /><br />Your final test case will perhaps look quite different from mine, but you may notice some similar patterns. Ultimately, this URI validation code should be moved to a separate component. Perhaps it could eventually be used as the basis for yet another Java URI implementation.<br /><div style="overflow:auto;height:750px;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.uri_regex;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">java.util.Arrays.asList;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">org.junit.Assert.assertFalse;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">org.junit.Assert.assertTrue;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.lang.reflect.Array;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.ArrayList;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Collection;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.HashSet;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">nl.flotsam.xeger.Xeger;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.Test;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">com.google.common.base.Function;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">URIRegExTest</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">SCHEME_REGEX</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"[a-zA-Z][a-zA-Z0-9\\+\\-\\.]*"</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">AUTHORITY_REGEX</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"(((([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\);:\\&=\\+$,]|(%[a-fA-F0-9]{2}))*)\\@)?((((([a-zA-Z0-9](([a-zA-Z0-9\\-])*[a-zA-Z0-9])?)\\.)*([a-zA-Z](([a-zA-Z0-9\\-])*[a-zA-Z0-9])?)(\\.)?)|([0-9]+((\\.[0-9]+){3})))(:[0-9]*)?))?|([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\)$,;:\\@\\&=\\+]|(%[a-fA-F0-9]{2}))+"</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">PATH_REGEX</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"((/(([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*)*))*)|(([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\);\\?:\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\);/\\?:\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*))?"</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">QUERY_REGEX</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\);/\\?:\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*"</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">FRAGMENT_REGEX</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\);/\\?:\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*"</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">URI_REFERENCE_REGEX</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"(([a-zA-Z][a-zA-Z0-9\\+\\-\\.]*:((((//((((([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\);:\\&=\\+$,]|(%[a-fA-F0-9]{2}))*)\\@)?((((([a-zA-Z0-9](([a-zA-Z0-9\\-])*[a-zA-Z0-9])?)\\.)*([a-zA-Z](([a-zA-Z0-9\\-])*[a-zA-Z0-9])?)(\\.)?)|([0-9]+((\\.[0-9]+){3})))(:[0-9]*)?))?|([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\)$,;:\\@\\&=\\+]|(%[a-fA-F0-9]{2}))+)(/(([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*)*))*)?)|(/(([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*)*))*))(\\?([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\);/\\?:\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*)?)|(([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\);\\?:\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\);/\\?:\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*)))|(((//((((([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\);:\\&=\\+$,]|(%[a-fA-F0-9]{2}))*)\\@)?((((([a-zA-Z0-9](([a-zA-Z0-9\\-])*[a-zA-Z0-9])?)\\.)*([a-zA-Z](([a-zA-Z0-9\\-])*[a-zA-Z0-9])?)(\\.)?)|([0-9]+((\\.[0-9]+){3})))(:[0-9]*)?))?|([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\)$,;:\\@\\&=\\+]|(%[a-fA-F0-9]{2}))+)(/(([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*)*))*)?)|(/(([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*)*))*)|(([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\);\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))+(/(([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*)*)(/(([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*(;([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\):\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*)*))*)?))(\\?([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\);/\\?:\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*)?))?(\\#([a-zA-Z0-9\\-_\\.!\\~\\*'\\(\\);/\\?:\\@\\&=\\+$,]|(%[a-fA-F0-9]{2}))*)?"</span><span style="color: rgb(0,0,0);">;</span><br /><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">NUMBER_OF_TESTS</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">100000;</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">theSchemeRegExIsNecessaryAndSufficient()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">verifyTheRegEx(SCHEME_REGEX,</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Function<String,</span> <span style="color: rgb(0,0,0);">Boolean>()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Boolean</span> <span style="color: rgb(0,0,0);">apply(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">s)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">scheme(s);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">});</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">theAuthorityRegExIsNecessaryAndSufficient()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">verifyTheRegEx(AUTHORITY_REGEX,</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Function<String,</span> <span style="color: rgb(0,0,0);">Boolean>()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Boolean</span> <span style="color: rgb(0,0,0);">apply(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">s)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">authority(s);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">});</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">thePathRegExIsNecessaryAndSufficient()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">verifyTheRegEx(PATH_REGEX,</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Function<String,</span> <span style="color: rgb(0,0,0);">Boolean>()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Boolean</span> <span style="color: rgb(0,0,0);">apply(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">s)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">path(s);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">});</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">theQueryRegExIsNecessaryAndSufficient()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">verifyTheRegEx(QUERY_REGEX,</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Function<String,</span> <span style="color: rgb(0,0,0);">Boolean>()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Boolean</span> <span style="color: rgb(0,0,0);">apply(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">s)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">query(s);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">});</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">theFragmentRegExIsNecessaryAndSufficient()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">verifyTheRegEx(FRAGMENT_REGEX,</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Function<String,</span> <span style="color: rgb(0,0,0);">Boolean>()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Boolean</span> <span style="color: rgb(0,0,0);">apply(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">s)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">fragment(s);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">});</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">theURIReferenceRegExIsNecessaryAndSufficient()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">verifyTheRegEx(URI_REFERENCE_REGEX,</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Function<String,</span> <span style="color: rgb(0,0,0);">Boolean>()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Boolean</span> <span style="color: rgb(0,0,0);">apply(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">s)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">uri_reference(s);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">});</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">verifyTheRegEx(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">pattern,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Function<String,</span> <span style="color: rgb(0,0,0);">Boolean></span> <span style="color: rgb(0,0,0);">f)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Xeger</span> <span style="color: rgb(0,0,0);">generator</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Xeger(pattern);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">0;</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">NUMBER_OF_TESTS;</span> <span style="color: rgb(0,0,0);">i++)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">generated</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">generator.generate();</span><br /> <span style="color: rgb(0,0,0);">assertTrue(String.format(</span><span style="color: rgb(42,0,255);">"Verifying the value '%s'."</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">generated),</span> <span style="color: rgb(0,0,0);">f.apply(generated));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Xeger</span> <span style="color: rgb(0,0,0);">negativeGenerator</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Xeger(negate(pattern));</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">0;</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">NUMBER_OF_TESTS;</span> <span style="color: rgb(0,0,0);">i++)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">generated</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">negativeGenerator.generate();</span><br /> <span style="color: rgb(0,0,0);">assertFalse(String.format(</span><span style="color: rgb(42,0,255);">"Verifying the negative '%s'."</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">generated),</span> <span style="color: rgb(0,0,0);">f.apply(generated));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Character></span> <span style="color: rgb(0,0,0);">mark;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Character></span> <span style="color: rgb(0,0,0);">reserved;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Character></span> <span style="color: rgb(0,0,0);">pchar;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Character></span> <span style="color: rgb(0,0,0);">userinfo;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Character></span> <span style="color: rgb(0,0,0);">reg_name;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Character></span> <span style="color: rgb(0,0,0);">scheme;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Character></span> <span style="color: rgb(0,0,0);">rel_segment;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Character></span> <span style="color: rgb(0,0,0);">uric_no_slash;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">mark</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">HashSet<Character>(asList(</span><span style="color: rgb(42,0,255);">'-'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'_'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'.'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'!'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'~'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'*'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'\''</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'('</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">')'</span><span style="color: rgb(0,0,0);">));</span><br /> <span style="color: rgb(0,0,0);">reserved</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">HashSet<Character>(asList(</span><span style="color: rgb(42,0,255);">';'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'/'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'?'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">':'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'@'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'&'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'='</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'+'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'$'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">','</span><span style="color: rgb(0,0,0);">));</span><br /> <span style="color: rgb(0,0,0);">pchar</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">HashSet<Character>(asList(</span><span style="color: rgb(42,0,255);">':'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'@'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'&'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'='</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'+'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'$'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">','</span><span style="color: rgb(0,0,0);">));</span><br /> <span style="color: rgb(0,0,0);">userinfo</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">HashSet<Character>(asList(</span><span style="color: rgb(42,0,255);">';'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">':'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'&'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'='</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'+'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'$'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">','</span><span style="color: rgb(0,0,0);">));</span><br /> <span style="color: rgb(0,0,0);">reg_name</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">HashSet<Character>(asList(</span><span style="color: rgb(42,0,255);">'$'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">','</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">';'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">':'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'@'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'&'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'='</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'+'</span><span style="color: rgb(0,0,0);">));</span><br /> <span style="color: rgb(0,0,0);">scheme</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">HashSet<Character>(asList(</span><span style="color: rgb(42,0,255);">'+'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'-'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'.'</span><span style="color: rgb(0,0,0);">));</span><br /> <span style="color: rgb(0,0,0);">rel_segment</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">HashSet<Character>(asList(</span><span style="color: rgb(42,0,255);">';'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'@'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'&'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'='</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'+'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'$'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">','</span><span style="color: rgb(0,0,0);">));</span><br /> <span style="color: rgb(0,0,0);">uric_no_slash</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">HashSet<Character>(asList(</span><span style="color: rgb(42,0,255);">';'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'?'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">':'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'@'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'&'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'='</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'+'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">'$'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">','</span><span style="color: rgb(0,0,0);">));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">uri_reference(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">s)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">uri_reference(codePoints(s));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">uri_reference(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[][]</span> <span style="color: rgb(0,0,0);">partition</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">partition(codePoints,</span> <span style="color: rgb(42,0,255);">'#'</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">uri</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">partition[0];</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">fragment</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">partition[1];</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">(uri.length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">0</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">absoluteURI(uri)</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">relativeURI(uri))</span><br /> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">(fragment.length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">0</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">fragment(subarray(fragment,</span> <span style="color: rgb(0,0,0);">1,</span> <span style="color: rgb(0,0,0);">fragment.length</span> <span style="color: rgb(0,0,0);">-</span> <span style="color: rgb(0,0,0);">1)));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">absoluteURI(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[][]</span> <span style="color: rgb(0,0,0);">partition</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">partition(codePoints,</span> <span style="color: rgb(42,0,255);">':'</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">scheme</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">partition[0];</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">part</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">partition[1].length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">0</span> <span style="color: rgb(0,0,0);">?</span> <span style="color: rgb(0,0,0);">partition[1]</span> <span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(0,0,0);">subarray(partition[1],</span> <span style="color: rgb(0,0,0);">1,</span><br /> <span style="color: rgb(0,0,0);">partition[1].length</span> <span style="color: rgb(0,0,0);">-</span> <span style="color: rgb(0,0,0);">1);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">scheme(scheme)</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">(heir_part(part)</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">opaque_part(part));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">relativeURI(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[][]</span> <span style="color: rgb(0,0,0);">partition</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">partition(codePoints,</span> <span style="color: rgb(42,0,255);">'?'</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">path</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">partition[0];</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">query</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">partition[1];</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">(net_path(path)</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">abs_path(path)</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">rel_path(path))</span><br /> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">(query.length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">0</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">query(subarray(query,</span> <span style="color: rgb(0,0,0);">1,</span> <span style="color: rgb(0,0,0);">query.length</span> <span style="color: rgb(0,0,0);">-</span> <span style="color: rgb(0,0,0);">1)));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">heir_part(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[][]</span> <span style="color: rgb(0,0,0);">partition</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">partition(codePoints,</span> <span style="color: rgb(42,0,255);">'?'</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">path</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">partition[0];</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">query</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">partition[1];</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">(net_path(path)</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">abs_path(path))</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">(query.length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">0</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">query(subarray(query,</span> <span style="color: rgb(0,0,0);">1,</span> <span style="color: rgb(0,0,0);">query.length</span> <span style="color: rgb(0,0,0);">-</span> <span style="color: rgb(0,0,0);">1)));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">path(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">s)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">path(codePoints(s));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">path(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">codePoints.length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">0</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">abs_path(codePoints)</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">opaque_part(codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">opaque_part(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(codePoints.length</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">1)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">theFirst</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">nextSymbol(0,</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">theRest</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">subarray(codePoints,</span> <span style="color: rgb(0,0,0);">theFirst.length,</span> <span style="color: rgb(0,0,0);">codePoints.length</span> <span style="color: rgb(0,0,0);">-</span> <span style="color: rgb(0,0,0);">theFirst.length);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">uric_no_slash(theFirst)</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">uric_star(theRest);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">uric_no_slash(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">isUnreservedOrEscapedOrSpecial(uric_no_slash,</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">net_path(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(codePoints.length</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">2)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">firstChar</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">codePoints[0];</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">secondChar</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">codePoints[1];</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">authority_and_abs_path</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">subarray(codePoints,</span> <span style="color: rgb(0,0,0);">2,</span> <span style="color: rgb(0,0,0);">codePoints.length</span> <span style="color: rgb(0,0,0);">-</span> <span style="color: rgb(0,0,0);">2);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[][]</span> <span style="color: rgb(0,0,0);">partition</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">partition(authority_and_abs_path,</span> <span style="color: rgb(42,0,255);">'/'</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">authority</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">partition[0];</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">abs_path</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">partition[1];</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">firstChar</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(42,0,255);">'/'</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">secondChar</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(42,0,255);">'/'</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">authority(authority)</span><br /> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">(abs_path.length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">0</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">abs_path(abs_path));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">rel_path(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(codePoints.length</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">1)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[][]</span> <span style="color: rgb(0,0,0);">partition</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">partition(codePoints,</span> <span style="color: rgb(42,0,255);">'/'</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">rel_segment</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">partition[0];</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">abs_path</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">partition[1];</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">rel_segment(rel_segment)</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">(abs_path.length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">0</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">abs_path(abs_path));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">abs_path(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(codePoints.length</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">1)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">slash</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">codePoints[0];</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">path_segments</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">subarray(codePoints,</span> <span style="color: rgb(0,0,0);">1,</span> <span style="color: rgb(0,0,0);">codePoints.length</span> <span style="color: rgb(0,0,0);">-</span> <span style="color: rgb(0,0,0);">1);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">slash</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(42,0,255);">'/'</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">path_segments(path_segments);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">rel_segment(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">atLeastOneUnreservedOrEscapedOrSpecial(rel_segment,</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">scheme(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">s)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">scheme(codePoints(s));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">scheme(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(codePoints.length</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">1)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(!alpha(codePoints[0]))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">1;</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">codePoints.length;</span> <span style="color: rgb(0,0,0);">i++)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer</span> <span style="color: rgb(0,0,0);">c</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">codePoints[i];</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(!(alphanum(c)</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">contains(scheme,</span> <span style="color: rgb(0,0,0);">c)))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">authority(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">s)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">authority(codePoints(s));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">authority(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">server(codePoints)</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">reg_name(codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">reg_name(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">atLeastOneUnreservedOrEscapedOrSpecial(reg_name,</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">server(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(codePoints.length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">0)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[][]</span> <span style="color: rgb(0,0,0);">userinfoAndHostport</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">split(</span><span style="color: rgb(42,0,255);">'@'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(userinfoAndHostport.length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">1)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">hostport(userinfoAndHostport[0]);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(userinfoAndHostport.length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">2)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">userinfo(userinfoAndHostport[0])</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">hostport(userinfoAndHostport[1]);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">userinfo(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">anyNumberOfUnreservedOrEscapedOrSpecial(userinfo,</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">hostport(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(codePoints.length</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">1)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[][]</span> <span style="color: rgb(0,0,0);">hostAndPort</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">split(</span><span style="color: rgb(42,0,255);">':'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(!host(hostAndPort[0]))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(hostAndPort.length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">1</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">hostAndPort.length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">2</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">port(hostAndPort[1]))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">host(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">hostname(codePoints)</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">ipv4address(codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">hostname(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(codePoints.length</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">1)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[][]</span> <span style="color: rgb(0,0,0);">labels</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">split(</span><span style="color: rgb(42,0,255);">'.'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">0;</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">labels.length</span> <span style="color: rgb(0,0,0);">-</span> <span style="color: rgb(0,0,0);">1;</span> <span style="color: rgb(0,0,0);">i++)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(!domainlabel(labels[i]))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">toplabel(labels[labels.length</span> <span style="color: rgb(0,0,0);">-</span> <span style="color: rgb(0,0,0);">1]);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">domainlabel(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">label(</span><span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Function<Integer,</span> <span style="color: rgb(0,0,0);">Boolean>()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Boolean</span> <span style="color: rgb(0,0,0);">apply(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer</span> <span style="color: rgb(0,0,0);">i)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">alphanum(i);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">},</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">toplabel(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">label(</span><span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Function<Integer,</span> <span style="color: rgb(0,0,0);">Boolean>()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Boolean</span> <span style="color: rgb(0,0,0);">apply(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer</span> <span style="color: rgb(0,0,0);">i)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">alpha(i);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">},</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">ipv4address(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[][]</span> <span style="color: rgb(0,0,0);">parts</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">split(</span><span style="color: rgb(42,0,255);">'.'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(parts.length</span> <span style="color: rgb(0,0,0);">!=</span> <span style="color: rgb(0,0,0);">4)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">part</span> <span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(0,0,0);">parts)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(part.length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">0)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer</span> <span style="color: rgb(0,0,0);">d</span> <span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(0,0,0);">part)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(!digit(d))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">port(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(!digit(i))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">path_segments(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[][]</span> <span style="color: rgb(0,0,0);">path_segments</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">split(</span><span style="color: rgb(42,0,255);">'/'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">segment</span> <span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(0,0,0);">path_segments)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(!eachSymbol(</span><span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Function<Integer[],</span> <span style="color: rgb(0,0,0);">Boolean>()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Boolean</span> <span style="color: rgb(0,0,0);">apply(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">ps)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">segment(ps);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">},</span> <span style="color: rgb(0,0,0);">segment))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">segment(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[][]</span> <span style="color: rgb(0,0,0);">segments</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">split(</span><span style="color: rgb(42,0,255);">';'</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">pchar</span> <span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(0,0,0);">segments)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(!param(pchar))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">param(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">anyNumberOfUnreservedOrEscapedOrSpecial(pchar,</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">query(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">s)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">query(codePoints(s));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">query(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">uric_star(codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">fragment(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">s)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">fragment(codePoints(s));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">fragment(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">uric_star(codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">uric_star(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">anyNumberOfUnreservedOrEscapedOrSpecial(reserved,</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">unreserved(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">codePoint)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">alphanum(codePoint)</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">mark(codePoint);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">mark(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">codePoint)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">contains(mark,</span> <span style="color: rgb(0,0,0);">codePoint);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">escaped(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">codePoints.length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">3</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">isChar(codePoints[0])</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">codePoints[0]</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(42,0,255);">'%'</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">hex(codePoints[1])</span><br /> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">hex(codePoints[2]);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">hex(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">codePoint)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(digit(codePoint))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(alpha(codePoint))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">letter</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">Character.toLowerCase(codePoint);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(42,0,255);">'a'</span> <span style="color: rgb(0,0,0);"><=</span> <span style="color: rgb(0,0,0);">letter</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">letter</span> <span style="color: rgb(0,0,0);"><=</span> <span style="color: rgb(42,0,255);">'f'</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">alphanum(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">codePoint)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">digit(codePoint)</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">alpha(codePoint);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">digit(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">codePoint)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(isChar(codePoint))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">char</span> <span style="color: rgb(0,0,0);">c</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">char</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">codePoint;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(42,0,255);">'0'</span> <span style="color: rgb(0,0,0);"><=</span> <span style="color: rgb(0,0,0);">c</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">c</span> <span style="color: rgb(0,0,0);"><=</span> <span style="color: rgb(42,0,255);">'9'</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">alpha(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">codePoint)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(isChar(codePoint))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">char</span> <span style="color: rgb(0,0,0);">c</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">char</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">codePoint;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(42,0,255);">'a'</span> <span style="color: rgb(0,0,0);"><=</span> <span style="color: rgb(0,0,0);">c</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">c</span> <span style="color: rgb(0,0,0);"><=</span> <span style="color: rgb(42,0,255);">'z'</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(42,0,255);">'A'</span> <span style="color: rgb(0,0,0);"><=</span> <span style="color: rgb(0,0,0);">c</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">c</span> <span style="color: rgb(0,0,0);"><=</span> <span style="color: rgb(42,0,255);">'Z'</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Integer[][]</span> <span style="color: rgb(0,0,0);">partition(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">is,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">char</span> <span style="color: rgb(0,0,0);">c)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">thePivot</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">indexOf(c,</span> <span style="color: rgb(0,0,0);">is);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">theLeft;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">theRight;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(thePivot</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">0)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">theLeft</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">is;</span><br /> <span style="color: rgb(0,0,0);">theRight</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">{};</span><br /> <span style="color: rgb(0,0,0);">}</span> <span style="font-weight: bold; color: rgb(127,0,85);">else</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">theLeft</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">subarray(is,</span> <span style="color: rgb(0,0,0);">0,</span> <span style="color: rgb(0,0,0);">thePivot);</span><br /> <span style="color: rgb(0,0,0);">theRight</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">subarray(is,</span> <span style="color: rgb(0,0,0);">thePivot,</span> <span style="color: rgb(0,0,0);">is.length</span> <span style="color: rgb(0,0,0);">-</span> <span style="color: rgb(0,0,0);">thePivot);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Integer[][]</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(0,0,0);">theLeft,</span> <span style="color: rgb(0,0,0);">theRight</span> <span style="color: rgb(0,0,0);">};</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">indexOf(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">char</span> <span style="color: rgb(0,0,0);">c,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">0;</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">codePoints.length;</span> <span style="color: rgb(0,0,0);">i++)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">next</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">codePoints[i];</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(next</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">c)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">i;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">-1;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">atLeastOneUnreservedOrEscapedOrSpecial(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Character></span> <span style="color: rgb(0,0,0);">special,</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">codePoints.length</span> <span style="color: rgb(0,0,0);">></span> <span style="color: rgb(0,0,0);">0</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">anyNumberOfUnreservedOrEscapedOrSpecial(special,</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">anyNumberOfUnreservedOrEscapedOrSpecial(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Character></span> <span style="color: rgb(0,0,0);">special,</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">eachSymbol(</span><span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Function<Integer[],</span> <span style="color: rgb(0,0,0);">Boolean>()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Boolean</span> <span style="color: rgb(0,0,0);">apply(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">ps)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">isUnreservedOrEscapedOrSpecial(special,</span> <span style="color: rgb(0,0,0);">ps);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">},</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">isUnreservedOrEscapedOrSpecial(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Character></span> <span style="color: rgb(0,0,0);">special,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(codePoints.length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">1)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">unreserved(codePoints[0])</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">contains(special,</span> <span style="color: rgb(0,0,0);">codePoints[0]);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">escaped(codePoints);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">contains(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Character></span> <span style="color: rgb(0,0,0);">cs,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">codePoint)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">isChar(codePoint)</span> <span style="color: rgb(0,0,0);">&&</span> <span style="color: rgb(0,0,0);">cs.contains(Character.valueOf((</span><span style="font-weight: bold; color: rgb(127,0,85);">char</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">codePoint));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">label(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Function<Integer,</span> <span style="color: rgb(0,0,0);">Boolean></span> <span style="color: rgb(0,0,0);">firstChar,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(codePoints.length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">0)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(codePoints.length</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">1)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">firstChar.apply(codePoints[0]);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer</span> <span style="color: rgb(0,0,0);">first</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">codePoints[0];</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer</span> <span style="color: rgb(0,0,0);">alphanum</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">codePoints[codePoints.length</span> <span style="color: rgb(0,0,0);">-</span> <span style="color: rgb(0,0,0);">1];</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">alphanums</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">subarray(codePoints,</span> <span style="color: rgb(0,0,0);">1,</span> <span style="color: rgb(0,0,0);">codePoints.length</span> <span style="color: rgb(0,0,0);">-</span> <span style="color: rgb(0,0,0);">2);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(!firstChar.apply(first)</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">!alphanum(alphanum))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(0,0,0);">alphanums)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(i</span> <span style="color: rgb(0,0,0);">!=</span> <span style="color: rgb(42,0,255);">'-'</span> <span style="color: rgb(0,0,0);">||</span> <span style="color: rgb(0,0,0);">!alphanum(i))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Integer[][]</span> <span style="color: rgb(0,0,0);">split(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">char</span> <span style="color: rgb(0,0,0);">delim,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Integer[]></span> <span style="color: rgb(0,0,0);">parts</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">ArrayList<Integer[]>();</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">0;</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">codePoints.length;)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">part</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">nextPart(delim,</span> <span style="color: rgb(0,0,0);">i,</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="color: rgb(0,0,0);">parts.add(part);</span><br /> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">+=</span> <span style="color: rgb(0,0,0);">part.length</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">1;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">parts.toArray(</span><span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Integer[parts.size()][]);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">nextPart(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">char</span> <span style="color: rgb(0,0,0);">delim,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">start,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">start;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(;</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">codePoints.length;</span> <span style="color: rgb(0,0,0);">i++)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(codePoints[i]</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">delim)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">break</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">pchar</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">subarray(codePoints,</span> <span style="color: rgb(0,0,0);">start,</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">-</span> <span style="color: rgb(0,0,0);">start);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">pchar;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">subarray(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">is,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">start,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">length)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">subarray(Integer.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">is,</span> <span style="color: rgb(0,0,0);">start,</span> <span style="color: rgb(0,0,0);">length);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@SuppressWarnings(</span><span style="color: rgb(42,0,255);">"unchecked"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);"><T></span> <span style="color: rgb(0,0,0);">T[]</span> <span style="color: rgb(0,0,0);">subarray(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Class<?></span> <span style="color: rgb(0,0,0);">type,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">T[]</span> <span style="color: rgb(0,0,0);">ts,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">start,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">length)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">T[]</span> <span style="color: rgb(0,0,0);">sub</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">(T[])</span> <span style="color: rgb(0,0,0);">Array.newInstance(type,</span> <span style="color: rgb(0,0,0);">length);</span><br /> <span style="color: rgb(0,0,0);">System.arraycopy(ts,</span> <span style="color: rgb(0,0,0);">start,</span> <span style="color: rgb(0,0,0);">sub,</span> <span style="color: rgb(0,0,0);">0,</span> <span style="color: rgb(0,0,0);">length);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">sub;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">eachSymbol(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Function<Integer[],</span> <span style="color: rgb(0,0,0);">Boolean></span> <span style="color: rgb(0,0,0);">f,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">0;</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">codePoints.length;)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">next</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">nextSymbol(i,</span> <span style="color: rgb(0,0,0);">codePoints);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(!f.apply(next))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">+=</span> <span style="color: rgb(0,0,0);">next.length;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">nextSymbol(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">i,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Integer...</span> <span style="color: rgb(0,0,0);">codePoints)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(codePoints[i]</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(42,0,255);">'%'</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(i</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">2</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">codePoints.length)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(0,0,0);">codePoints[i],</span> <span style="color: rgb(0,0,0);">codePoints[i</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">1],</span> <span style="color: rgb(0,0,0);">codePoints[i</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">2]</span> <span style="color: rgb(0,0,0);">};</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(0,0,0);">codePoints[i]</span> <span style="color: rgb(0,0,0);">};</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">isChar(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">codePoint)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">Character.charCount(codePoint)</span> <span style="color: rgb(0,0,0);">==</span> <span style="color: rgb(0,0,0);">1;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">negate(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">regEx)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">String.format(</span><span style="color: rgb(42,0,255);">"~(%s)"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">regEx);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Integer[]</span> <span style="color: rgb(0,0,0);">codePoints(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">s)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Integer></span> <span style="color: rgb(0,0,0);">codePoints</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">ArrayList<Integer>();</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">s</span> <span style="color: rgb(0,0,0);">==</span> <span style="font-weight: bold; color: rgb(127,0,85);">null</span> <span style="color: rgb(0,0,0);">?</span> <span style="color: rgb(0,0,0);">0</span> <span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(0,0,0);">s.length();</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">0;</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">length;)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">codepoint</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">s.codePointAt(i);</span><br /> <span style="color: rgb(0,0,0);">codePoints.add(codepoint);</span><br /> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">+=</span> <span style="color: rgb(0,0,0);">Character.charCount(codepoint);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">codePoints.toArray(</span><span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Integer[codePoints.size()]);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br /><h4>How to Use:</h4><br />Now that we have a regex to validate URIs, we can use it for such purposes as <a href="http://timezra.blogspot.com/2010/04/regex-to-validate-uml-stereotype.html">validating UML stereotype attributes</a>. Always keep in mind that regex parsers can vary quite a bit in their supported operations. I have tried to limit this regex to a standard set of characters, but a few still require tweaking for the EMF RegEx parser to process them, i.e., <strong>&</strong> <strong>~</strong> <strong>@</strong> all must be <em>unescaped</em> (the backslashes must be removed, whereas <a href="http://www.brics.dk/~amoeller/automaton">automaton</a> requires them).<br /><br /><h4>Conclusion:</h4><br />The primary purpose of this tutorial has been to provide a complete regular expression that validates the syntax of a candidate URI. Along the way, we have also discovered a technique for test-driving the incremental creation of complex regular expressions.Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com0tag:blogger.com,1999:blog-106449775438946661.post-68171447204594935942010-04-20T23:55:00.000-07:002010-05-22T01:32:34.263-07:00RegEx to Validate UML Stereotype Attributes<h4>Goal</h4><br />By the end of this tutorial, we will have a technique for restricting UML Stereotype values with regular expressions using the Eclipse UML2 Tools and Ecore ExtendedMetaData.<br /><br /><h4>Create a UML Profile</h4><br />First, we will need to install the <strong>Modelling - > UML2 Tools SDK</strong> from the Galileo update site. Make yourself a peanut butter sandwich while you wait for the download, or if you already have the tools, then eat a piece of chocolate as a reward for not eating all those calories.<br /><br />Our project is to create a Stereotype called Contact, which extends UML::Actor. A Contact is an Actor with contact information, which, in this case, is a single phone number. A US phone number can easily be validated with a regular expression. For this project, we can assume that all the Actors we will ever deal with will have US phone numbers.<br /><br />We will start off by creating a plain ol' project, here called <em>UML Regex Validation</em>, and in this project, we will create a new UML Profile Definition, <em>RegexValidation.profile.uml</em>, with a Profile Model object as the root.<br />Since a Contact is an Actor, we will import <em>uml::Actor</em> from the <strong>UML Editor -> Profile -> Reference Metaclass</strong> menu.<br />Now we can create our <em>Contact</em> Stereotype and extend <em>uml::Actor</em> from the <strong>UML Editor -> Stereotype -> Create Extension</strong> menu.<br />We now have a simple Stereotype that we can apply to an Actor.<br />From the <strong>UML Editor -> Profile -> Define</strong> menu, we will generate our initial <em>RegexValidation</em> Ecore UML MetaData.<br /><br /><h4>Test The Stereotype</h4><br />We can create an Activity Diagram file, <em>RegexValidationTest.uml</em>, with a Package as the root. In the root Package, <em>Contacts</em>, we will create an Actor. Some call him <em>Tim</em>.<br />From the <strong>UML Editor</strong> menu, we will load the resource <em>RegexValidation.profile.uml</em> and apply the Profile for <em>RegexValidation</em> to <em>Contacts</em>. We are now ready to apply the <em>RegexValidation::Contact</em> Stereotype to <em>Tim</em>.<br />Now that we know that we can apply the Profile and the Stereotype, we will remove the Profile and Stereotype applications in <em>RegexValidationTest.uml</em>. When we re-define our Profile, the XMI IDs will also all be re-generated and these Profile and Stereotype applications will be invalidated. <br /><br /><h4>The Restricted Stereotype Attribute</h4><br />In <em>RegexValidation.profile.uml</em>, we will create our custom Primitive Type, <em>USPhoneNumberType</em>.<br />The General of this type should be <em>UMLPrimitiveTypes::String</em>.<br />Now we can add an EAnnotation to the <em>USPhoneNumberType</em>, with source value <em>http:///org/eclipse/emf/ecore/util/ExtendedMetaData</em>.<br />We will set the ExtendedMetaData Details as follows:<br /><ul><br /><li><strong>name</strong> -> <strong>USPhoneNumberType</strong></li><br /><li><strong> baseType </strong> -> <strong>http://www.eclipse.org/emf/2003/XMLType#string</strong></li><br /><li><strong> pattern </strong> -> <strong>1?\W*([2-9][0-8][0-9])\W*([2-9][0-9]{2})\W*([0-9]{4})(\se?x?t?(\d*))?</strong></li><br /></ul><br />This particular <a href="http://stackoverflow.com/questions/123559/a-comprehensive-regex-for-phone-number-validation">US phone number regular expression</a> is based on the <a href="http://en.wikipedia.org/wiki/North_American_Numbering_Plan">NANP specification</a>.<br /><br />We will also need to apply the Ecore Profile to the RegexValidation Profile in order to Stereotype the <em>USPhoneNumberType</em> as an <em>Ecore::EDataType</em>. We will send Ecore a hint that the <em>USPhoneNumberType Instance Class Name</em> should be <em>java.lang.String</em>.<br /><br />Now, we can create an Owned Property, <em>PhoneNumber</em>, in the Contact Stereotype, and its type can be <em>RegexValidation::USPhoneNumberType</em>.<br /><br />We will again Define our RegexValidation Profile from the <strong>UML Editor</strong> menu, but now we must explicitly <strong>Process</strong> the <strong>Annotation Details</strong> in the configuration dialog. The default configuration simply reports on Ecore MetaData. <br /><img src="http://farm5.static.flickr.com/4026/4540248748_32491b5a9b_o.png" alt="Process Annotation Details"/><br /><br />If you are curious, the details section of the status dialog should indicate what MetaData has been processed.<br />The generated UML MetaData Definition will now include an EDataType for the USPhoneNumberType, which is restricted by our NANP phone number pattern.<br /><img src="http://farm5.static.flickr.com/4065/4540248826_cc5d621401_o.png" alt="The Defined UML Ecore Package with Extended MetaData"><br /><br />We can now re-open our <em>RegexValidationTest.uml</em>, re-apply the RegexValidation Profile to the <em>Contacts</em> Package, and re-apply the <em>RegexValidation::Contact</em> Stereotype to <em>Tim</em>, the Actor.<br />We should now see our new PhoneNumber attribute in the Properties View.<br /><br />Try entering an invalid phone number, such as 123-456-7890, in the Properties text field. What do you see? When you press enter, is the invalid value bound to the attribute?<br /><img src="http://farm5.static.flickr.com/4048/4540248922_6b282fc6ff_o.png" alt="Invalid Phone Number Error" /><br /><br />Now try entering a valid phone number, such as 555-555-5555. What happens?<br /><img src="http://farm3.static.flickr.com/2755/4540248874_d978951d6f_o.png" alt="Valid Phone Number" /><br /><br /><h4>Common Types</h4><br />With the technique outlined above, common regular expression patterns can be easily applied to more UML Stereotype attributes through Ecore MetaData: <a href="http://timezra.blogspot.com/2010/05/regex-to-validate-uris.html">URIs</a>, <a href="http://www.webmonkey.com/2008/08/four_regular_expressions_to_check_email_addresses">email addresses</a> (although, <a href="http://ex-parrot.com/~pdw/Mail-RFC822-Address.html">the more complete regex</a> has given me the <a href="http://en.wikipedia.org/wiki/Spinning_wait_cursor">SPOD</a> in Eclipse in the past), or any number of other <a href="http://regexlib.com/">publicly available regular expressions</a>.<br /><br /><h4>Next</h4><br />Now that we have a way to constrain stereotype attributes with a RegEx, wouldn't it be swell if there were a way to <a href="http://timezra.blogspot.com/2010/05/testing-stereotype-attribute-regex.html">test that the restrictions work as expected</a>?Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com0tag:blogger.com,1999:blog-106449775438946661.post-76349946410632567972010-04-16T22:01:00.000-07:002010-04-16T22:53:39.222-07:00Erlang in EclipseToday I uploaded my first meager attempt at an <a href="http://www.erlang.org/">Erlang</a> plug-in built using the <a href="http://www.eclipse.org/dltk/">Eclipse DLTK</a>. It is hosted on <a href="http://bitbucket.org/">bitbucket</a> using <a href="http://mercurial.selenic.com/">mercurial</a>.<br /><br />If you are interested in seeing the code and monkeying around, feel free to clone the repository:<br /><div style="overflow:auto;width:60%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /> hg clone http://bitbucket.org/timezra/eclerlangipse<br /></div><br /><br />The project is currently pre-pre-alpha, and I am publishing it simply because I will be making some sweeping changes over the next few weeks and am not comfortable making those changes without putting the code under version control. Chief among those changes are the use of <a href="http://www.eclipse.org/m2e/">Tycho</a> for the build; the use of an Erlang node instead of escripts for syntax parsing, compilation and warning/error feedback; Typerl and Dialyzer builders; test features; an update site; and better syntax tree setup. Also, I am always happy to have extra eyes on my code and I appreciate the feedback.<br /><br />Over the next few weeks, I will expand on the following topics:<br /><ul><br /><li>Why Erlang?</li><br /><li>Why Eclipse?</li><br /><li>Why Mercurial?</li><br /><li>What is the backlog of features?</li><br /><li>Why is the name so stupid?</li><br /><li>What have I been doing for this past year?</li><br /><li>What could I possibly be thinking?</li><br /></ul>Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com0tag:blogger.com,1999:blog-106449775438946661.post-34387411184004237082009-06-30T15:06:00.000-07:002009-06-30T15:41:54.163-07:00Setting Maven Properties With Groovy<h4>Goal</h4><br />While I generally try to configure, rather than script, Maven builds, sometimes the publicly-available plug-ins do not provide enough flexibility to work-around limitations in third-party libraries through configuration alone. Fortunately, <a href="http://groovy.codehaus.org/GMaven">GMaven</a> exposes the flexibility of Groovy in a Maven plug-in. This post demonstrates how to use a Groovy script to transform a Maven project property. Such a transformation is sometimes necessary, for example, for <a href="http://jira.codehaus.org/browse/MDEP-89">transforming a Windows-style path to Unix</a>. For myself, I formalized this solution while trying to <a href="http://cvs.pgfoundry.org/cgi-bin/cvsweb.cgi/pljava/org.postgresql.pljava/docs/userguide.html?rev=1.15#install_jar_">install a jar</a> in PostgreSQL automatically during the artifact deployment phase.<br /><br /><h4>Display a Maven Project Property</h4><br />We can start by creating a simple <a href="http://m2eclipse.codehaus.org/">m2eclipse</a> project, by adding a single property with a default value and by configuring the <em>pom.xml</em> to display this property on the console during a lifecycle event (here, during compilation).<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0"</span> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span><br /> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span>4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>timezra.blog.maven.groovy.properties<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>timezra.blog.maven.groovy.properties<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span>timezra.blog.maven.groovy.properties<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>0.0.1-SNAPSHOT<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">description</span><span style="color: rgb(0,128,128);">></span>An example of setting Maven properties using Groovy.<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">description</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">properties</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">unixy_build_directory</span><span style="color: rgb(0,128,128);">></span>${project.build.directory}<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">unixy_build_directory</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">properties</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.apache.maven.plugins<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>maven-antrun-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>show-unixy_build_directory!<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span>compile<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span>run<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">tasks</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">echo</span><span style="color: rgb(0,128,128);">></span>unixy_build_directory: ${unixy_build_directory}<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">echo</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">tasks</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><br />If we run the <b>compile</b> goal, we will see the bound Maven property in the build output.<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /> > mvn compile<br /> ....<br /> [INFO] [antrun:run {execution: show-unixy_build_directory!}]<br /> [INFO] Executing tasks<br /> [echo] unixy_build_directory: C:\programming\workspaces\blog\timezra.blog.maven.groovy.properties\target<br /> [INFO] Executed tasks<br /> ....<br /></div><br /><br /><a href="http://groovy.codehaus.org/GMaven+-+Executing+Groovy+Code">Setting up the <em>gmaven-plugin</em></a> is straightforward, as is re-binding the property with Groovy in the <em>pom.xml</em>.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(0,0,0);">.</span>...<span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.codehaus.groovy.maven<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>gmaven-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>set-unixy_build_directory!<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span>compile<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span>execute<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">classpath</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">element</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>commons-lang<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>commons-lang<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.4<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">element</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">classpath</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">source</span><span style="color: rgb(0,128,128);">></span><br /> if (org.apache.commons.lang.SystemUtils.IS_OS_WINDOWS) {<br /> project.properties.unixy_build_directory =<br /> project.build.directory.replace("\\", "/");<br /> }<br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">source</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><b>NB</b>: This example takes a Windows file path and transforms the backslashes to forward slashes. If you are not running Windows, then this example is moot. Please, experiment with the bindings in the <em>pom.xml</em> to demonstrate clearly to yourself that the property has really, really, really been re-bound.<br /><br />When compiling, we will now see output indicating that the Groovy script has mutated the Maven property.<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /> > mvn compile<br /> ....<br /> [INFO] [antrun:run {execution: show-unixy_build_directory!}]<br /> [INFO] Executing tasks<br /> [echo] unixy_build_directory: C:/programming/workspaces/blog/timezra.blog.maven.groovy.properties/target<br /> [INFO] Executed tasks<br /> ....<br /></div><br /><br /><h4>Conclusion</h4><br />With a few lines of configuration and a simple Groovy script, we are able to modify Maven properties as part of a lifecycle event. This tool adds even more power to your Maven builds, but, as stated above, it should be used cautiously and only when absolutely necessary. If there is a solution already in the Maven toolkit, then that is generally better. Not all project requirements fit in the box, however, and this example exposes a simple way to handle the non-ideal.Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com13tag:blogger.com,1999:blog-106449775438946661.post-48368177087486261202009-06-25T16:24:00.000-07:002009-06-29T10:42:15.153-07:00Maven And Weblogic<h4>Goal</h4><br />This post is a follow-up to a previous entry on <a href="http://timezra.blogspot.com/2008/07/run-weblogic-ant-tasks-without.html">running Weblogic Ant tasks without calling setDomainEnv</a>. The purpose is to perform the same actions from Maven. Fortunately, the <a href="http://mojo.codehaus.org/weblogic-maven-plugin/">weblogic-maven-plugin</a> does not have the same requirement for setting environment variables from outside the build script. Unfortunately, development on the mojos appears to be a few versions behind the latest release of Weblogic. The code and examples here demonstrate how to use this Maven plug-in to run goals for deloying a WAR, building a web service skeleton and generating a web service client for Weblogic 10.3.<br /><br /><h4>Listing the Applications Deployed to Weblogic</h4><br />We can begin by creating an m2eclipse Maven project, <em>timezra.blog.maven.weblogic</em>, with the webapp-jee5 archetype. The Wizard materializes a simple hello world application that will be packaged as a WAR.<br /><br />In order to list the applications deployed to Weblogic, we first need to setup a Weblogic domain if we do not already have one. For this example, we can create one called <em>maven_example</em> using the defaults provided by the Configuration Wizard.<br />There is already <a href="http://firstpartners.net/kb/index.php/Deploying_to_Weblogic_using_Maven">a good starting point</a> for configuring the <em>weblogic-maven-plugin</em> in our <em>pom.xml</em>, but for 10.3 these instructions are incomplete. One problem becomes evident when we compose an Eclipse Run Configuration for the <b>weblogic:listapps</b> goal (being sure to use the External Maven 2.10 Runtime).<br /><img src="http://farm4.static.flickr.com/3537/3660501833_ca0d269982.jpg" alt="An Eclipse Run Configuration for the weblogic:listapps goal."/><br /><br />In our console, we would see a stack trace.<br /><div style="overflow:auto;width:100%; height:500px; padding:5px;color:red;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /><span style="color: rgb(42,0,255);text-decoration:underline;">java.lang.NoClassDefFoundError</span>: weblogic/utils/Debug<br /> at weblogic.Deployer.<clinit>(<span style="color: rgb(42,0,255);text-decoration:underline;">Deployer.java:23</span>)<br /> at org.codehaus.mojo.weblogic.DeployMojoBase.executeDeployer(<span style="color: rgb(42,0,255);text-decoration:underline;">DeployMojoBase.java:509</span>)<br /> at org.codehaus.mojo.weblogic.ListAppsMojo.execute(<span style="color: rgb(42,0,255);text-decoration:underline;">ListAppsMojo.java:51</span>)<br /> at org.apache.maven.plugin.DefaultPluginManager.executeMojo(<span style="color: rgb(42,0,255);text-decoration:underline;">DefaultPluginManager.java:483</span>)<br /> at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoals(<span style="color: rgb(42,0,255);text-decoration:underline;">DefaultLifecycleExecutor.java:678</span>)<br /> at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeStandaloneGoal(<span style="color: rgb(42,0,255);text-decoration:underline;">DefaultLifecycleExecutor.java:553</span>)<br /> at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoal(<span style="color: rgb(42,0,255);text-decoration:underline;">DefaultLifecycleExecutor.java:523</span>)<br /> at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeGoalAndHandleFailures(<span style="color: rgb(42,0,255);text-decoration:underline;">DefaultLifecycleExecutor.java:371</span>)<br /> at org.apache.maven.lifecycle.DefaultLifecycleExecutor.executeTaskSegments(<span style="color: rgb(42,0,255);text-decoration:underline;">DefaultLifecycleExecutor.java:332</span>)<br /> at org.apache.maven.lifecycle.DefaultLifecycleExecutor.execute(<span style="color: rgb(42,0,255);text-decoration:underline;">DefaultLifecycleExecutor.java:181</span>)<br /> at org.apache.maven.DefaultMaven.doExecute(<span style="color: rgb(42,0,255);text-decoration:underline;">DefaultMaven.java:356</span>)<br /> at org.apache.maven.DefaultMaven.execute(<span style="color: rgb(42,0,255);text-decoration:underline;">DefaultMaven.java:137</span>)<br /> at org.apache.maven.cli.MavenCli.main(<span style="color: rgb(42,0,255);text-decoration:underline;">MavenCli.java:356</span>)<br /> at sun.reflect.NativeMethodAccessorImpl.invoke0(<span style="color: rgb(42,0,255);text-decoration:underline;">Native Method</span>)<br /> at sun.reflect.NativeMethodAccessorImpl.invoke(<span style="color: rgb(42,0,255);text-decoration:underline;">NativeMethodAccessorImpl.java:39</span>)<br /> at sun.reflect.DelegatingMethodAccessorImpl.invoke(<span style="color: rgb(42,0,255);text-decoration:underline;">DelegatingMethodAccessorImpl.java:25</span>)<br /> at java.lang.reflect.Method.invoke(<span style="color: rgb(42,0,255);text-decoration:underline;">Method.java:597</span>)<br /> at org.codehaus.classworlds.Launcher.launchEnhanced(<span style="color: rgb(42,0,255);text-decoration:underline;">Launcher.java:315</span>)<br /> at org.codehaus.classworlds.Launcher.launch(<span style="color: rgb(42,0,255);text-decoration:underline;">Launcher.java:255</span>)<br /> at org.codehaus.classworlds.Launcher.mainWithExitCode(<span style="color: rgb(42,0,255);text-decoration:underline;">Launcher.java:430</span>)<br /> at org.codehaus.classworlds.Launcher.main(<span style="color: rgb(42,0,255);text-decoration:underline;">Launcher.java:375</span>)<br />Caused by: java.lang.ClassNotFoundException: weblogic.utils.Debug<br /> at java.net.URLClassLoader$1.run(<span style="color: rgb(42,0,255);text-decoration:underline;">URLClassLoader.java:200</span>)<br /> at java.security.AccessController.doPrivileged(<span style="color: rgb(42,0,255);text-decoration:underline;">Native Method</span>)<br /> at java.net.URLClassLoader.findClass(<span style="color: rgb(42,0,255);text-decoration:underline;">URLClassLoader.java:188</span>)<br /> at java.lang.ClassLoader.loadClass(<span style="color: rgb(42,0,255);text-decoration:underline;">ClassLoader.java:307</span>)<br /> at org.codehaus.classworlds.RealmClassLoader.loadClassDirect(<span style="color: rgb(42,0,255);text-decoration:underline;">RealmClassLoader.java:195</span>)<br /> at org.codehaus.classworlds.DefaultClassRealm.loadClass(<span style="color: rgb(42,0,255);text-decoration:underline;">DefaultClassRealm.java:255</span>)<br /> at org.codehaus.classworlds.DefaultClassRealm.loadClass(<span style="color: rgb(42,0,255);text-decoration:underline;">DefaultClassRealm.java:274</span>)<br /> at org.codehaus.classworlds.RealmClassLoader.loadClass(<span style="color: rgb(42,0,255);text-decoration:underline;">RealmClassLoader.java:214</span>)<br /> at java.lang.ClassLoader.loadClass(<span style="color: rgb(42,0,255);text-decoration:underline;">ClassLoader.java:252</span>)<br /> at java.lang.ClassLoader.loadClassInternal(<span style="color: rgb(42,0,255);text-decoration:underline;">ClassLoader.java:320</span>)<br /> ... 21 more<br /></span><br /></div><br /><br />We must manually install a few libraries in addition to those <a href="http://firstpartners.net/kb/index.php/Deploying_to_Weblogic_using_Maven">the Wiki entry</a> lists into our local Maven repository.<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /> mvn install:install-file -DgroupId=weblogic -DartifactId=weblogic -Dversion=10.3 -Dpackaging=jar -Dfile=C:\webservers\bea\wlserver_10.3\server\lib\weblogic.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=webservices -Dversion=10.3 -Dpackaging=jar -Dfile=C:\webservers\bea\wlserver_10.3\server\lib\webservices.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.weblogic.rmi.client -Dversion=1.4.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.weblogic.rmi.client_1.4.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=javax.enterprise.deploy -Dversion=1.2 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\javax.enterprise.deploy_1.2.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.management.core -Dversion=2.3.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.management.core_2.3.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.weblogic.security.identity -Dversion=1.1.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.weblogic.security.identity_1.1.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.weblogic.security -Dversion=1.0.0.0_5-0-2-0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.weblogic.security_1.0.0.0_5-0-2-0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.weblogic.security.wls -Dversion=1.0.0.0_5-0-2-0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.weblogic.security.wls_1.0.0.0_5-0-2-0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.weblogic.workmanager -Dversion=1.4.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.weblogic.workmanager_1.4.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.transaction -Dversion=2.5.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.transaction_2.5.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.logging -Dversion=1.4.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.logging_1.4.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.utils.classloaders -Dversion=1.4.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.utils.classloaders_1.4.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.descriptor -Dversion=1.4.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.descriptor_1.4.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.timers -Dversion=1.4.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.timers_1.4.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.weblogic.socket.api -Dversion=1.0.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.weblogic.socket.api_1.0.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.common.security.api -Dversion=1.0.0.0_5-0-2-0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.common.security.api_1.0.0.0_5-0-2-0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.weblogic.security.digest -Dversion=1.0.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.weblogic.security.digest_1.0.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.weblogic.lifecycle -Dversion=1.1.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.weblogic.lifecycle_1.1.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.workarea -Dversion=1.4.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.workarea_1.4.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.utils.wrapper -Dversion=1.3.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.utils.wrapper_1.3.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.store -Dversion=1.4.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.store_1.4.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.management.jmx -Dversion=1.1.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.management.jmx_1.1.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.descriptor.wl -Dversion=1.1.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.descriptor.wl_1.1.0.0.jar<br /></span><br /></div><br /><br />We will configure the plug-in to depend on these and other publicly available libraries in our project <em>pom.xml</em>.<br /><div style="overflow:auto;width:100%;height:750px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0"</span> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span><br /> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span>4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>timezra.blog.maven.weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>timezra.blog.maven.weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">packaging</span><span style="color: rgb(0,128,128);">></span>war<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">packaging</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>0.0.1-SNAPSHOT<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span>timezra.blog.maven.weblogic JEE5 Webapp<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://maven.apache.org<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>javax.servlet<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>servlet-api<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.5<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>javax.servlet.jsp<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>jsp-api<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.1<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.apache.maven.plugins<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>maven-compiler-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.0.2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">source</span><span style="color: rgb(0,128,128);">></span>1.5<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">source</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">target</span><span style="color: rgb(0,128,128);">></span>1.5<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">target</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.codehaus.mojo<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>weblogic-maven-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.9.2-SNAPSHOT<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">adminServerHostName</span><span style="color: rgb(0,128,128);">></span>localhost<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">adminServerHostName</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">adminServerPort</span><span style="color: rgb(0,128,128);">></span>7001<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">adminServerPort</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">adminServerProtocol</span><span style="color: rgb(0,128,128);">></span>t3<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">adminServerProtocol</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">userId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">userId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">password</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">password</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">upload</span><span style="color: rgb(0,128,128);">></span>false<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">upload</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">remote</span><span style="color: rgb(0,128,128);">></span>false<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">remote</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">verbose</span><span style="color: rgb(0,128,128);">></span>false<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">verbose</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">debug</span><span style="color: rgb(0,128,128);">></span>false<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">debug</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">targetNames</span><span style="color: rgb(0,128,128);">></span>AdminServer<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">targetNames</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.utils.full<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.i18n<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.weblogic.rmi.client<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>javax.enterprise.deploy<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.management.core<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.3.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.weblogic.security.wls<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.0.0.0_5-0-2-0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.weblogic.security<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.0.0.0_5-0-2-0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.weblogic.security.identity<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.1.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.weblogic.workmanager<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.transaction<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.5.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.logging<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.utils.classloaders<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.descriptor<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.timers<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.weblogic.socket.api<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.0.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.common.security.api<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.0.0.0_5-0-2-0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.weblogic.security.digest<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.0.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.weblogic.lifecycle<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.1.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.workarea<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.utils.wrapper<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.3.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>javax.transaction<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>jta<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.1<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.store<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.management.jmx<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.1.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.descriptor.wl<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.1.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">finalName</span><span style="color: rgb(0,128,128);">></span>timezra.blog.maven.weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">finalName</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">pluginRepositories</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">pluginRepository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>Maven Snapshots<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://snapshots.repository.codehaus.org/<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">snapshots</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">enabled</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">enabled</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">snapshots</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">releases</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">enabled</span><span style="color: rgb(0,128,128);">></span>false<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">enabled</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">releases</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">pluginRepository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">pluginRepositories</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br />The output from our Eclipse <b>weblogic:listapps</b> launcher should now show<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /> There is no application to list.<br /></div><br /><br /><h4>Deploying a WAR</h4><br />Our Maven archetype has already configured the packaging for our application, and building the WAR is not Weblogic-specific. Deploying to the AdminServer is, however.<br />If we were to create another Eclipse Run Configuration, here called <b>full_deploy</b>, which calls the <b>package</b> and <b>deploy</b> goals, we would see an error.<br /><div style="overflow:auto;width:100%; height:500px; padding:5px;color:red;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br />[ERROR] BUILD ERROR<br />[INFO] ------------------------------------------------------------------------<br />[INFO] Failed to configure plugin parameters for: org.apache.maven.plugins:maven-deploy-plugin:2.4<br /><br />check that the following section of the pom.xml is present and correct:<br /><br /><distributionManagement><br /> <!-- use the following if you're not using a snapshot version. --><br /> <repository><br /> <id>repo</id><br /> <name>Repository Name</name><br /> <url>scp://host/path/to/repo</url><br /> </repository><br /> <!-- use the following if you ARE using a snapshot version. --><br /> <snapshotRepository><br /> <id>repo</id><br /> <name>Repository Name</name><br /> <url>scp://host/path/to/repo</url><br /> </snapshotRepository><br /></distributionManagement><br /></span><br /></div><br />For this example, it is sufficient for the distribution manager to point to our local repository and to hook into the <b>weblogic:deploy</b> goal in our <em>pom.xml</em>.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(0,0,0);">.</span>...<span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>deploy.to.weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span>deploy<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span>deploy<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.codehaus.mojo<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">distributionManagement</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">snapshotRepository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>localRepository<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span>Local Repository<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>file://${HOMEDRIVE}/Docume~1/${USERNAME}/.m2/repository<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">snapshotRepository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">distributionManagement</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br />If you are developing on Windows, at this point you may see a misleading error about an incorrect protocol.<br /><div style="overflow:auto;width:100%;padding:5px;color:red;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br />[INFO] Weblogic Deployment parameters [-adminurl, t3://localhost:7001, -username, weblogic, -password, weblogic, -name, timezra.blog.maven.weblogic, -targets, AdminServer, -source, C:\programming\workspaces\blog\timezra.blog.maven.weblogic\target/timezra.blog.maven.weblogic.war, -deploy]<br />weblogic.Deployer invoked with options: -adminurl t3://localhost:7001 -username weblogic -name timezra.blog.maven.weblogic -targets AdminServer -source C:\programming\workspaces\blog\timezra.blog.maven.weblogic\target/timezra.blog.maven.weblogic.war -deploy<br /><Jun 24, 2009 4:36:08 PM PDT> <Info> <J2EE Deployment SPI> <BEA-260121> <Initiating deploy operation for application, timezra.blog.maven.weblogic [archive: C:\programming\workspaces\blog\timezra.blog.maven.weblogic\target\timezra.blog.maven.weblogic.war], to AdminServer .> <br />no protocol: and<br /></span><br /></div><br /><br />The problem is that <em>weblogic-maven-plugin</em> goals do not properly handle spaces in the classpath. <a href="http://jira.codehaus.org/browse/MOJO-759">The solution</a> is simply to eliminate these spaces in the <em>~/$USER/.m2/settings.xml</em> file.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">settings</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">localRepository</span><span style="color: rgb(0,128,128);">></span>${HOMEDRIVE}/Docume~1/${USERNAME}/.m2/repository<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">localRepository</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">settings</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><br />The output from our Eclipse <em>weblogic:listapps</em> launcher should now show<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /> timezra.blog.maven.weblogic<br /> Number of Applications Found : 1<br /></span><br /></div><br />If we open http://localhost:7001/timezra.blog.maven.weblogic/ in a browser, we will see <b>Hello World!</b><br /><br /><h4>Compile A Web Service</h4><br />The trial-and-error process for deploying a Web Service is very similar to publishing our packaged WAR: setup project dependencies, implement the service in Java, call the <b>weblogic:jwsc</b> goal, work out any unresolved dependencies and deploy the application.<br />Our web service will depend on annotations from the <em>javax.jws</em> library, which is provided by Weblogic. We can install this JAR, as above.<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /> mvn install:install-file -DgroupId=weblogic -DartifactId=javax.jws -Dversion=2.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\javax.jws_2.0.jar<br /></span><br /></div><br /><br />We will configure this project dependency in our <em>pom.xml</em>.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(0,0,0);">.</span>...<span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>javax.jws<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br />We can write an echo service with interface <em>/src/main/java/timezra/blog/maven/weblogic/ws/IEcho.java</em>, that simply resonates the client's input.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.maven.weblogic.ws;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">interface</span> <span style="color: rgb(0,0,0);">IEcho</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">echo(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">holla);</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br />We will implement the web service as described in <a href="http://timezra.blogspot.com/2008/09/spring-hibernate-and-jax-ws-webservices.html">a previous post</a> in <em>/src/main/java/timezra/blog/maven/weblogic/ws/Echo.java</em>.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.maven.weblogic.ws;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.jws.WebMethod;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.jws.WebParam;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.jws.WebResult;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.jws.WebService;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.jws.WebParam.Mode;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.jws.soap.SOAPBinding;</span><br /><br /><span style="color: rgb(0,0,0);">@WebService(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"Echo"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">targetNamespace</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">Echo.NAMESPACE,</span> <span style="color: rgb(0,0,0);">serviceName</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"Echo"</span><span style="color: rgb(0,0,0);">)</span><br /><span style="color: rgb(0,0,0);">@SOAPBinding(style</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">SOAPBinding.Style.DOCUMENT,</span> <span style="color: rgb(0,0,0);">use</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">SOAPBinding.Use.LITERAL,</span> <span style="color: rgb(0,0,0);">parameterStyle</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">SOAPBinding.ParameterStyle.WRAPPED)</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">Echo</span> <span style="font-weight: bold; color: rgb(127,0,85);">implements</span> <span style="color: rgb(0,0,0);">IEcho</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">NAMESPACE</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"http://timezra.blog.maven.weblogic"</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">ELLIPSIS</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">" ... "</span><span style="color: rgb(0,0,0);">;</span><br /><br /> <span style="color: rgb(0,0,0);">@WebMethod(operationName</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"echo"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@WebResult(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"holla_back"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">targetNamespace</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">NAMESPACE)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">echo(@WebParam(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"holla"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">targetNamespace</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">NAMESPACE,</span> <span style="color: rgb(0,0,0);">mode</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">Mode.IN)</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">holla)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(holla</span> <span style="color: rgb(0,0,0);">==</span> <span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String[]</span> <span style="color: rgb(0,0,0);">what</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">holla.split(</span><span style="color: rgb(42,0,255);">"\\s"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">StringBuilder</span> <span style="color: rgb(0,0,0);">echo</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">StringBuilder(what[0]);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">1;</span> <span style="color: rgb(0,0,0);">i</span> <span style="color: rgb(0,0,0);"><</span> <span style="color: rgb(0,0,0);">what.length;</span> <span style="color: rgb(0,0,0);">i++)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">echo.append(</span><span style="color: rgb(42,0,255);">' '</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">echo.append(what[i]);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">theLastWord</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">what[what.length</span> <span style="color: rgb(0,0,0);">-</span> <span style="color: rgb(0,0,0);">1];</span><br /> <span style="color: rgb(0,0,0);">echo.append(ELLIPSIS);</span><br /> <span style="color: rgb(0,0,0);">echo.append(theLastWord);</span><br /> <span style="color: rgb(0,0,0);">echo.append(ELLIPSIS);</span><br /> <span style="color: rgb(0,0,0);">echo.append(theLastWord);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">echo.toString();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br />The <b>weblogic:jwsc</b> goal has dependencies on more Weblogic modules.<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.annogen -Dversion=1.2.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.annogen_1.2.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.descriptor.j2ee.binding -Dversion=1.1.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.descriptor.j2ee.binding_1.1.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.xml.staxb.runtime -Dversion=1.3.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.xml.staxb.runtime_1.3.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.xml.beaxmlbeans -Dversion=1.0.0.0_2-4-0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.xml.beaxmlbeans_1.0.0.0_2-4-0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.descriptor.j2ee -Dversion=1.1.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.descriptor.j2ee_1.1.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=javax.ejb -Dversion=3.0.1 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\javax.ejb_3.0.1.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.xml.xmlbeans -Dversion=1.0.0.0_2-4-0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.xml.xmlbeans_1.0.0.0_2-4-0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.weblogic.stax -Dversion=1.4.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.weblogic.stax_1.4.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=javax.xml.rpc -Dversion=1.2.1 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\javax.xml.rpc_1.2.1.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.xml.staxb.buildtime -Dversion=1.3.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.xml.staxb.buildtime_1.3.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=glassfish.jaxws.rt -Dversion=2.1.3 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\glassfish.jaxws.rt_2.1.3.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.descriptor.wl.binding -Dversion=1.1.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.descriptor.wl.binding_1.1.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.descriptor.settable.binding -Dversion=1.4.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.descriptor.settable.binding_1.4.0.0.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=com.bea.core.weblogic.saaj -Dversion=1.3.0.0 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\com.bea.core.weblogic.saaj_1.3.0.0.jar<br /></span><br /></div><br /><br />We will add these plug-in dependencies to the <em>pom.xml</em> along with configuration parameters specific to <b>weblogic:jwsc</b>.<br /><div style="overflow:auto;width:100%;height:750px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(0,0,0);">.</span>...<span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.codehaus.mojo<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>weblogic-maven-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.9.2-SNAPSHOT<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">outputName</span><span style="color: rgb(0,128,128);">></span>${project.artifactId}<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">outputName</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">contextPath</span><span style="color: rgb(0,128,128);">></span>${project.artifactId}<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">contextPath</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">descriptor</span><span style="color: rgb(0,128,128);">></span>${basedir}/src/main/webapp/WEB-INF/web.xml<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">descriptor</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.annogen<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.2.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.descriptor.j2ee.binding<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.1.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.xml.staxb.runtime<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.3.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.xml.beaxmlbeans<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.0.0.0_2-4-0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.descriptor.j2ee<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.1.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>com.sun<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>tools<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.6.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>system<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">systemPath</span><span style="color: rgb(0,128,128);">></span>${java.home}/../lib/tools.jar<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">systemPath</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>javax.ejb<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.1<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.xml.xmlbeans<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.0.0.0_2-4-0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.weblogic.stax<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>javax.xml.rpc<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.2.1<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.xml.staxb.buildtime<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.3.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>glassfish.jaxws.rt<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.1.3<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>javax.mail<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>mail<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.4.1<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.descriptor.wl.binding<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.1.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.descriptor.settable.binding<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>com.bea.core.weblogic.saaj<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.3.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br />Now we can run a new Eclipse launcher that calls <b>weblogic:jwsc</b> in the same way that we setup launchers for <b>weblogic:listapps</b>. We see that the web service artifacts are correctly generated in the <em>target</em> directory, and the URL for the new web service is correctly merged into the <em>target/timezra.blog.maven.weblogic/WEB-INF/web.xml</em>. Unfortunately, if we package and deploy the application, this merging of information in the <em>web.xml</em> will be overwritten with the contents of <em>src/main/webapp/WEB-INF/web.xml</em> (Try it if you do not believe me, if you did not follow or if you would like to discover for yourself why this is the case!). Fortunately, there is a way to automate the generation of web service and the correct packaging of the artifacts and compiled sources with some extra configuration in the <em>pom.xml</em>.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(0,0,0);">.</span>...<span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>generate.web.services<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span>package<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span>jwsc<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.codehaus.mojo<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>weblogic-maven-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.9.2-SNAPSHOT<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.apache.maven.plugins<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>maven-war-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.1-beta-1<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span>package<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">phase</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span>war<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goal</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">goals</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">execution</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">executions</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br />We can view the published WSDL in a browser at address http://localhost:7001/timezra.blog.maven.weblogic/Echo?WSDL and we can use our favorite web service client application (here, I use <a href="http://www.soapui.org/">soapUI</a>) to run a few tests.<br /><img src="http://farm3.static.flickr.com/2463/3660501869_2f36b91f2d_o.png" alt="Holla-ing to the Echo Web Service through soapUI." /><br /><br /><h4>Generate a Web Service Client</h4><br />Now that we have a deployment infrastructure and a working web service, we can create a client for that service. The current version of the <em>weblogic-maven-plugin</em> (2.9.2-SNAPSHOT) supports two goals for generating a web service client, <b>weblogic:clientgen</b> and <b>weblogic:clientgen9</b>. Unfortunately, neither works with Weblogic 10. If we were to call <b>weblogic:clientgen9</b>, for example, we would see an error similar to this:<br /><div style="overflow:auto;width:100%;padding:5px;color:red;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br />[INFO] ------------------------------------------------------------------------<br />[ERROR] BUILD ERROR<br />[INFO] ------------------------------------------------------------------------<br />[INFO] Internal error in the plugin manager executing goal 'org.codehaus.mojo:weblogic-maven-plugin:2.9.2-SNAPSHOT:clientgen9': Unable to find the mojo 'clientgen9' (or one of its required components) in the plugin 'org.codehaus.mojo:weblogic-maven-plugin'<br />(class: org/codehaus/mojo/weblogic/ClientGen9Mojo, method: execute signature: ()V) Incompatible object argument for function call<br />[INFO] ------------------------------------------------------------------------<br /></span><br /></div><br /><br />The only remedy I have seen to this issue is to modify the <em>weblogic-maven-plugin</em> and to install it in a local repository. After importing <a href="https://svn.codehaus.org/mojo/trunk/mojo/weblogic-maven-plugin">the project</a> into Eclipse, we can simply apply this patch to the project root.<br /><div style="overflow:auto;width:100%;height:750px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br />Index: pom.xml<br />===================================================================<br />--- pom.xml (revision 10022)<br />+++ pom.xml (working copy)<br />@@ -11,7 +11,7 @@<br /> <artifactId>weblogic-maven-plugin</artifactId><br /> <packaging>maven-plugin</packaging><br /> <name>Weblogic Maven Plugin</name><br />- <version>2.9.2-SNAPSHOT</version><br />+ <version>2.9.3-SNAPSHOT</version><br /> <inceptionYear>2005</inceptionYear><br /> <description><br /> This plugin will support various tasks within the Weblogic 8.1<br />@@ -95,6 +95,12 @@<br /> <artifactId>webservices</artifactId><br /> <version>[9.0,11.0)</version><br /> </dependency><br />+ <dependency><br />+ <groupId>weblogic</groupId><br />+ <artifactId>com.bea.core.utils.full</artifactId><br />+ <version>1.4.0.0</version><br />+ <scope>provided</scope><br />+ </dependency><br /> <dependency><br /> <groupId>org.apache.maven.shared</groupId><br /> <artifactId>maven-plugin-testing-harness</artifactId><br />@@ -126,4 +132,11 @@<br /> </plugin><br /> </plugins><br /> </reporting><br />+ <distributionManagement><br />+ <snapshotRepository><br />+ <id>localRepository</id><br />+ <name>Local Repository</name><br />+ <url>file://${HOMEDRIVE}/Docume~1/${USERNAME}/.m2/repository</url><br />+ </snapshotRepository><br />+ </distributionManagement><br /> </project><br />\ No newline at end of file<br />Index: .settings/org.eclipse.jdt.core.prefs<br />===================================================================<br />--- .settings/org.eclipse.jdt.core.prefs (revision 0)<br />+++ .settings/org.eclipse.jdt.core.prefs (revision 0)<br />@@ -0,0 +1,5 @@<br />+#Sat Jun 20 17:00:42 PDT 2009<br />+eclipse.preferences.version=1<br />+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2<br />+org.eclipse.jdt.core.compiler.compliance=1.4<br />+org.eclipse.jdt.core.compiler.source=1.3<br />Index: .settings/org.maven.ide.eclipse.prefs<br />===================================================================<br />--- .settings/org.maven.ide.eclipse.prefs (revision 0)<br />+++ .settings/org.maven.ide.eclipse.prefs (revision 0)<br />@@ -0,0 +1,9 @@<br />+#Sat Jun 20 17:00:25 PDT 2009<br />+activeProfiles=<br />+eclipse.preferences.version=1<br />+fullBuildGoals=process-test-resources<br />+includeModules=false<br />+resolveWorkspaceProjects=true<br />+resourceFilterGoals=process-resources resources\:testResources<br />+skipCompilerPlugin=true<br />+version=1<br />Index: src/main/java/org/codehaus/mojo/weblogic/ClientGen10Mojo.java<br />===================================================================<br />--- src/main/java/org/codehaus/mojo/weblogic/ClientGen10Mojo.java (revision 0)<br />+++ src/main/java/org/codehaus/mojo/weblogic/ClientGen10Mojo.java (revision 0)<br />@@ -0,0 +1,402 @@<br />+package org.codehaus.mojo.weblogic;<br />+<br />+/*<br />+ * Copyright 2008 The Apache Software Foundation.<br />+ *<br />+ * Licensed under the Apache License, Version 2.0 (the "License");<br />+ * you may not use this file except in compliance with the License.<br />+ * You may obtain a copy of the License at<br />+ *<br />+ * http://www.apache.org/licenses/LICENSE-2.0<br />+ *<br />+ * Unless required by applicable law or agreed to in writing, software<br />+ * distributed under the License is distributed on an "AS IS" BASIS,<br />+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.<br />+ * See the License for the specific language governing permissions and<br />+ * limitations under the License.<br />+ */<br />+<br />+import org.apache.maven.plugin.MojoExecutionException;<br />+import org.apache.tools.ant.Project;<br />+import org.apache.tools.ant.types.Path;<br />+import org.codehaus.mojo.weblogic.util.WeblogicMojoUtilities;<br />+import weblogic.wsee.tools.anttasks.ClientGenTask;<br />+<br />+import java.io.File;<br />+<br />+/**<br />+ * Runs Client Gen on a given WSDL. This client gen uses the BEA refactored client gen tool<br />+ * first appearing in weblogic 9. This is the preferred client gen tool for Weblogic 9.0 and<br />+ * newer.<br />+ *<br />+ * @author <a href="mailto:josborn@belltracy.com">Jon Osborn</a><br />+ * @version $Id: ClientGen10Mojo.java 8652 2009-01-13 01:13:28Z jonnio $<br />+ * @description This mojo will run client gen on a given WSDL. This client gen uses the BEA refactored client gen tool<br />+ * first appearing in weblogic 9. This is the preferred client gen tool for Weblogic 10.0 and newer.<br />+ * @goal clientgen10<br />+ * @requiresDependencyResolution compile<br />+ */<br />+public class ClientGen10Mojo<br />+ extends AbstractWeblogicMojo<br />+{<br />+<br />+ /**<br />+ * The filename of the war file to find the services. The file path is<br />+ * extracted from the artifact list.<br />+ *<br />+ * @parameter<br />+ */<br />+ private String warFileName;<br />+<br />+ /**<br />+ * The wsdl to client gen from. If warFileName is specified, this parameter<br />+ * is the root relative file to use when creating the URI for the wsdl.<br />+ *<br />+ * @parameter<br />+ */<br />+ private String inputWSDL;<br />+<br />+ /**<br />+ * The directory to output the generated code to.<br />+ *<br />+ * @parameter default-value="${basedir}/src/main/java"<br />+ */<br />+ private String outputDir;<br />+<br />+ /**<br />+ * The package name of the output code.<br />+ *<br />+ * @parameter default-value="com.test.webservice"<br />+ */<br />+ private String packageName;<br />+<br />+ /**<br />+ * The name of the service.<br />+ *<br />+ * @parameter<br />+ */<br />+ private String serviceName;<br />+<br />+ /**<br />+ * Output verbose messages<br />+ *<br />+ * @parameter default-value="false"<br />+ */<br />+ private boolean verbose;<br />+<br />+ /**<br />+ * Whether or not to use server types from the ear file in the client jar.<br />+ *<br />+ * @parameter default-value="false"<br />+ */<br />+ private boolean useServerTypes;<br />+<br />+ /**<br />+ * Sets whether or not to create the type conversions for a web service in<br />+ * the client.<br />+ *<br />+ * @parameter default-value="true"<br />+ */<br />+ private boolean autotype;<br />+<br />+ /**<br />+ * Sets whether or not to use the jaxRPCWrappedArrayStyle<br />+ *<br />+ * @parameter default-value="true"<br />+ */<br />+ private boolean jaxRPCWrappedArrayStyle;<br />+<br />+ /**<br />+ * This method will run client gen on the given WSDL.<br />+ *<br />+ * @throws MojoExecutionException Thrown if we fail to obtain the WSDL.<br />+ */<br />+ public void execute()<br />+ throws MojoExecutionException<br />+ {<br />+ super.execute();<br />+<br />+ if ( getLog().isInfoEnabled() )<br />+ {<br />+ getLog().info( "Weblogic client gen beginning " );<br />+ }<br />+ if ( getLog().isInfoEnabled() )<br />+ {<br />+ getLog().info( " Detailed client gen settings information " + this.toString() );<br />+ }<br />+<br />+ try<br />+ {<br />+ final ClientGenTask clientGen = new ClientGenTask();<br />+ // Set the classpath<br />+ final Project project = new Project();<br />+ project.setName( "clientgen" );<br />+ final Path path = new Path( project, WeblogicMojoUtilities<br />+ .getDependencies( this.getArtifacts(), this.getPluginArtifacts() ) );<br />+ clientGen.setProject( project );<br />+ clientGen.setClasspath( path );<br />+ clientGen.setVerbose( this.verbose );<br />+ clientGen.setDestDir( new File( this.outputDir ) );<br />+ clientGen.setPackageName( this.packageName );<br />+ clientGen.setIncludeGlobalTypes( this.useServerTypes );<br />+ clientGen.setJaxRPCWrappedArrayStyle( this.jaxRPCWrappedArrayStyle );<br />+ String wsdlUri;<br />+ if ( this.warFileName != null )<br />+ {<br />+ if ( getLog().isInfoEnabled() )<br />+ {<br />+ getLog().info(<br />+ " calculating wsdl URI from warFileName " + this.warFileName + " with wsdl " + this.inputWSDL );<br />+ }<br />+ wsdlUri = "jar:file:" + WeblogicMojoUtilities.getWarFileName( this.getArtifacts(), this.warFileName ) +<br />+ "!" + this.inputWSDL;<br />+ new File( this.inputWSDL ).toURI().toString();<br />+ if ( getLog().isInfoEnabled() )<br />+ {<br />+ getLog().info( " using " + wsdlUri + " for clientgen." );<br />+ }<br />+ }<br />+ else if ( this.inputWSDL.startsWith( "http" ) )<br />+ {<br />+ if ( getLog().isInfoEnabled() )<br />+ {<br />+ getLog().info( " using " + this.inputWSDL + " for clientgen." );<br />+ }<br />+ wsdlUri = this.inputWSDL;<br />+ }<br />+ else<br />+ {<br />+ wsdlUri = new File( this.inputWSDL ).toURI().toString();<br />+ if ( getLog().isInfoEnabled() )<br />+ {<br />+ getLog().info( " using " + wsdlUri + " for clientgen." );<br />+ }<br />+ }<br />+ clientGen.setWsdl( wsdlUri );<br />+ // set the service name if it is specified<br />+ if ( this.serviceName != null )<br />+ {<br />+ if ( getLog().isInfoEnabled() )<br />+ {<br />+ getLog().info( " generating client for service '" + this.serviceName + "'." );<br />+ }<br />+ clientGen.setServiceName( this.serviceName );<br />+ }<br />+ clientGen.execute();<br />+ }<br />+ catch ( Exception ex )<br />+ {<br />+ getLog().error( "Exception encountered during client gen", ex );<br />+ throw new MojoExecutionException( "Exception encountered during listapps", ex );<br />+ }<br />+ finally<br />+ {<br />+ WeblogicMojoUtilities.unsetWeblogicProtocolHandler();<br />+ }<br />+<br />+ if ( getLog().isInfoEnabled() )<br />+ {<br />+ getLog().info( "Weblogic client gen successful " );<br />+ }<br />+ }<br />+<br />+ /**<br />+ * Getter for property input WSDL.<br />+ *<br />+ * @return The value of input WSDL.<br />+ */<br />+ public String getInputWSDL()<br />+ {<br />+ return this.inputWSDL;<br />+ }<br />+<br />+ /**<br />+ * Setter for the input WSDL.<br />+ *<br />+ * @param inInputWSDL The value of input WSDL.<br />+ */<br />+ public void setInputWSDL( final String inInputWSDL )<br />+ {<br />+ this.inputWSDL = inInputWSDL;<br />+ }<br />+<br />+ /**<br />+ * Getter for property output dir.<br />+ *<br />+ * @return The value of output dir.<br />+ */<br />+ public String getOutputDir()<br />+ {<br />+ return this.outputDir;<br />+ }<br />+<br />+ /**<br />+ * Setter for the output dir.<br />+ *<br />+ * @param inOutputDir The value of output dir.<br />+ */<br />+ public void setOutputDir( final String inOutputDir )<br />+ {<br />+ this.outputDir = inOutputDir;<br />+ }<br />+<br />+ /**<br />+ * Getter for property package name.<br />+ *<br />+ * @return The value of package name.<br />+ */<br />+ public String getPackageName()<br />+ {<br />+ return this.packageName;<br />+ }<br />+<br />+ /**<br />+ * Setter for the package name.<br />+ *<br />+ * @param inPackageName The value of package name.<br />+ */<br />+ public void setPackageName( String inPackageName )<br />+ {<br />+ this.packageName = inPackageName;<br />+ }<br />+<br />+ /**<br />+ * Getter for property service name.<br />+ *<br />+ * @return The value of service name.<br />+ */<br />+ public String getServiceName()<br />+ {<br />+ return this.serviceName;<br />+ }<br />+<br />+ /**<br />+ * Setter for the service name.<br />+ *<br />+ * @param inServiceName The value of service name.<br />+ */<br />+ public void setServiceName( final String inServiceName )<br />+ {<br />+ this.serviceName = inServiceName;<br />+ }<br />+<br />+ /**<br />+ * toString method: creates a String representation of the object<br />+ *<br />+ * @return the String representation<br />+ */<br />+ public String toString()<br />+ {<br />+ StringBuffer buffer = new StringBuffer();<br />+ buffer.append( "ClientGen10Mojo[" );<br />+ buffer.append( "inputWSDL = " ).append( inputWSDL );<br />+ buffer.append( ", outputDir = " ).append( outputDir );<br />+ buffer.append( ", packageName = " ).append( packageName );<br />+ buffer.append( ", serviceName = " ).append( serviceName );<br />+ buffer.append( ", useServerTypes = " ).append( useServerTypes );<br />+ buffer.append( ", autotype = " ).append( autotype );<br />+ buffer.append( "]" );<br />+ return buffer.toString();<br />+ }<br />+<br />+ /**<br />+ * Getter for server types<br />+ *<br />+ * @return true if the client gen should use server type information<br />+ */<br />+ public boolean isUseServerTypes()<br />+ {<br />+ return useServerTypes;<br />+ }<br />+<br />+ /**<br />+ * Setter for server types<br />+ *<br />+ * @param useServerTypes - true if the client gen should use server types<br />+ */<br />+ public void setUseServerTypes( boolean useServerTypes )<br />+ {<br />+ this.useServerTypes = useServerTypes;<br />+ }<br />+<br />+ /**<br />+ * Getter for verbose messages<br />+ *<br />+ * @return true if the client gen should use verbose output<br />+ */<br />+ public boolean isVerbose()<br />+ {<br />+ return this.verbose;<br />+ }<br />+<br />+ /**<br />+ * Setter for verbose messages<br />+ *<br />+ * @param verbose - true of the clientgen should use verbose output<br />+ */<br />+ public void setVerbose( boolean verbose )<br />+ {<br />+ this.verbose = verbose;<br />+ }<br />+<br />+<br />+ /**<br />+ * Getter for autoType<br />+ *<br />+ * @return true if clientgen shoud autotype from the wsdl<br />+ */<br />+ public boolean isAutotype()<br />+ {<br />+ return this.autotype;<br />+ }<br />+<br />+ /**<br />+ * Setter for autoType<br />+ *<br />+ * @param autotype - true if the client should autotype<br />+ */<br />+ public void setAutotype( boolean autotype )<br />+ {<br />+ this.autotype = autotype;<br />+ }<br />+<br />+ /**<br />+ * Getter for warFileName<br />+ *<br />+ * @return the warFileName<br />+ */<br />+ public String getWarFileName()<br />+ {<br />+ return this.warFileName;<br />+ }<br />+<br />+ /**<br />+ * Setter for warFileName<br />+ *<br />+ * @param warFileName - the warFileName to set<br />+ */<br />+ public void setWarFileName( String warFileName )<br />+ {<br />+ this.warFileName = warFileName;<br />+ }<br />+<br />+ /**<br />+ * Getter for jaxRPCWrappedArrayStyle<br />+ *<br />+ * @return the jaxRPCWrappedArrayStyle<br />+ */<br />+ public boolean isJaxRPCWrappedArrayStyle()<br />+ {<br />+ return jaxRPCWrappedArrayStyle;<br />+ }<br />+<br />+ /**<br />+ * Setter for jaxRPCWrappedArrayStyle<br />+ *<br />+ * @param jaxRPCWrappedArrayStyle the jaxRPCWrappedArrayStyle to set<br />+ */<br />+ public void setJaxRPCWrappedArrayStyle( boolean jaxRPCWrappedArrayStyle )<br />+ {<br />+ this.jaxRPCWrappedArrayStyle = jaxRPCWrappedArrayStyle;<br />+ }<br />+}<br />Index: src/main/java/org/codehaus/mojo/weblogic/util/WeblogicMojoUtilities.java<br />===================================================================<br />--- src/main/java/org/codehaus/mojo/weblogic/util/WeblogicMojoUtilities.java (revision 10022)<br />+++ src/main/java/org/codehaus/mojo/weblogic/util/WeblogicMojoUtilities.java (working copy)<br />@@ -48,7 +48,7 @@<br /> {<br /> if ( "weblogic.utils".equals(System.getProperty("java.protocol.handler.pkgs") ) )<br /> {<br />- System.setProperty( "java.protocol.handler.pkgs", null );<br />+ System.clearProperty( "java.protocol.handler.pkgs" );<br /> }<br /> }<br /> <br />Index: src/test/java/org/codehaus/mojo/weblogic/SimpleGoalMojoTest.java<br />===================================================================<br />--- src/test/java/org/codehaus/mojo/weblogic/SimpleGoalMojoTest.java (revision 10022)<br />+++ src/test/java/org/codehaus/mojo/weblogic/SimpleGoalMojoTest.java (working copy)<br />@@ -128,6 +128,21 @@<br /> }<br /> <br /> /**<br />+ * Test that we can find the deploy goal<br />+ *<br />+ * @throws Exception when the lookup fails<br />+ * @see org.codehaus.mojo.weblogic.ClientGen10Mojo<br />+ */<br />+ public void testMojoClientGen10Goal()<br />+ throws Exception<br />+ {<br />+<br />+ final ClientGen10Mojo mojo = (ClientGen10Mojo) lookupMojo( "clientgen10", this.testPom );<br />+<br />+ assertNotNull( mojo );<br />+ }<br />+<br />+ /**<br /> * Test an invalid goal to be sure the valid ones are 'real'.<br /> *<br /> * @throws Exception - throws exception when something fails.<br /><br /></span><br /></div><br /><b>NB</b>: This patch has been submitted as a <a href="http://jira.codehaus.org/browse/MOJO-1396">bug report</a>. Please comment or vote on this bug to get it pushed through.<br />We will deploy this update to the plug-in (here, with version number 2.9.3-SNAPSHOT) by simply running the goal as <b>Maven install</b> from Eclipse.<br /><br />Now that we have a working client generation goal in our updated and installed plug-in, again, we will need to register a few more Weblogic libraries for our project.<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /> mvn install:install-file -DgroupId=weblogic -DartifactId=javax.jms -Dversion=1.1.1 -Dpackaging=jar -Dfile=C:\webservers\bea\modules\javax.jms_1.1.1.jar<br /> mvn install:install-file -DgroupId=weblogic -DartifactId=wseeclient -Dversion=10.3 -Dpackaging=jar -Dfile=C:\webservers\bea\wlserver_10.3\server\lib\wseeclient.jar<br /></span><br /></div><br /><br />We can add these new project and plug-in dependencies, along with necessary configuration parameters to the <em>pom.xml</em>. Generally, I do not automate client generation, as published WSDLs infrequently change. You may have different project requirements, however.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(0,0,0);">.</span>...<span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>wseeclient<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>10.3<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>javax.xml.rpc<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.2.1<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.codehaus.mojo<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>weblogic-maven-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.9.3-SNAPSHOT<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">inputWSDL</span><span style="color: rgb(0,128,128);">></span>http://localhost:7001/timezra.blog.maven.weblogic/Echo?WSDL<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">inputWSDL</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">packageName</span><span style="color: rgb(0,128,128);">></span>timezra.blog.maven.weblogic.ws.client<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">packageName</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">serviceName</span><span style="color: rgb(0,128,128);">></span>Echo<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">serviceName</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>weblogic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>javax.jms<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.1.1<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>provided<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br />Our business component, <em>src/main/java/timezra/blog/maven/weblogic/service/EchoService.java</em> invokes the generated client.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.maven.weblogic.service;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.rmi.RemoteException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.xml.rpc.ServiceException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">timezra.blog.maven.weblogic.ws.client.Echo_Service;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">timezra.blog.maven.weblogic.ws.client.Echo_Service_Impl;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">EchoService</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">say(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">phrase)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">try</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Echo_Service</span> <span style="color: rgb(0,0,0);">echoService</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Echo_Service_Impl();</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">echoService.getEchoSoapPort().echo(phrase);</span><br /> <span style="color: rgb(0,0,0);">}</span> <span style="font-weight: bold; color: rgb(127,0,85);">catch</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">RemoteException</span> <span style="color: rgb(0,0,0);">e)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(42,0,255);">"Putter, ka-chunk, piff."</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span> <span style="font-weight: bold; color: rgb(127,0,85);">catch</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">ServiceException</span> <span style="color: rgb(0,0,0);">e)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(42,0,255);">"Gurgle, burble, glug."</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br />We will need a way to mediate the client invokation and the display of the response, so we will create a <em>src/main/java/timezra/blog/maven/weblogic/controller/IsAnybodyThere.java</em> controller.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.maven.weblogic.controller;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.io.IOException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.servlet.ServletException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.servlet.http.HttpServlet;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.servlet.http.HttpServletRequest;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.servlet.http.HttpServletResponse;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">timezra.blog.maven.weblogic.service.EchoService;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">IsAnybodyThere</span> <span style="font-weight: bold; color: rgb(127,0,85);">extends</span> <span style="color: rgb(0,0,0);">HttpServlet</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">serialVersionUID</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">-8205256394812150098L;</span><br /><br /> <span style="color: rgb(0,0,0);">@Override</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">protected</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">doGet(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">HttpServletRequest</span> <span style="color: rgb(0,0,0);">req,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">HttpServletResponse</span> <span style="color: rgb(0,0,0);">resp)</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">ServletException,</span> <span style="color: rgb(0,0,0);">IOException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">echo</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">EchoService().say(</span><span style="color: rgb(42,0,255);">"Is there anybody in there?"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">req.setAttribute(</span><span style="color: rgb(42,0,255);">"echo"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">echo);</span><br /> <span style="color: rgb(0,0,0);">req.getRequestDispatcher(</span><span style="color: rgb(42,0,255);">"echo.jsp"</span><span style="color: rgb(0,0,0);">).forward(req,</span> <span style="color: rgb(0,0,0);">resp);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br />Our view, <em>src/main/webapp/echo.jsp</em>, will simply show the result of calling the service.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span>%@page contentType="text/html" pageEncoding="UTF-8"<span style="color: rgb(0,0,0);">%</span>><br /><span style="color: rgb(0,128,128);"><!</span><span style="color: rgb(63,127,127);">DOCTYPE</span> <span style="color: rgb(0,128,128);">HTML</span> <span style="color: rgb(128,128,128);">PUBLIC</span> <span style="color: rgb(0,128,128);">"-//W3C//DTD HTML 4.01 Transitional//EN"</span><br /> <span style="color: rgb(63,127,95);">"http://www.w3.org/TR/html4/loose.dtd"</span><span style="color: rgb(0,128,128);">></span><br /><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">html</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">head</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">meta</span> <span style="color: rgb(127,0,127);">http-equiv</span>=<span style="font-style: italic; color: rgb(42,0,255);">"Content-Type"</span> <span style="color: rgb(127,0,127);">content</span>=<span style="font-style: italic; color: rgb(42,0,255);">"text/html; charset=UTF-8"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">title</span><span style="color: rgb(0,128,128);">></span>JSP Page<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">title</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">head</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">body</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">h1</span><span style="color: rgb(0,128,128);">></span>${echo}<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">h1</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">body</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">html</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br />Finally, we will register our view in the web descriptor, <em>web.xml</em>.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;">....<br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">web-app</span> <span style="color: rgb(0,0,0);">.</span>...<span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">servlet</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">servlet-name</span><span style="color: rgb(0,128,128);">></span>IsAnybodyThere<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">servlet-name</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">servlet-class</span><span style="color: rgb(0,128,128);">></span>timezra.blog.maven.weblogic.controller.IsAnybodyThere<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">servlet-class</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">servlet</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">servlet-mapping</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">servlet-name</span><span style="color: rgb(0,128,128);">></span>IsAnybodyThere<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">servlet-name</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url-pattern</span><span style="color: rgb(0,128,128);">></span>/IsAnybodyThere<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url-pattern</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">servlet-mapping</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">web-app</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br />Now, when we run <b>full_deploy</b> and open http://localhost:7001/timezra.blog.maven.weblogic/IsAnybodyThere in a browser, we will see the message "Is there anybody in there? ... there? ... there?".<br /><br /><h4>Conclusion</h4><br />While it certainly would have been possible to hook the Maven Ant plugin to the build script presented in <a href="http://timezra.blogspot.com/2008/07/run-weblogic-ant-tasks-without.html">a previous post</a> for executing tasks that disguise the need to run the <em>setDomainEnv</em> script, this post provides a different approach through the existing <em>weblogic-maven-plugin</em> and thus eliminates the need for manipulating <em>setDomainEnv</em> entirely with a manageable amount of configuration in the <em>pom.xml</em>.<br /><br /><img src="http://farm4.static.flickr.com/3065/3660501853_fc9a785c30_o.png" alt="A Maven project that compiles a web service, generates a web service client, and deploys a WAR to Weblogic.">Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com30tag:blogger.com,1999:blog-106449775438946661.post-88960111389558916982009-05-26T20:29:00.000-07:002009-05-26T22:36:38.317-07:00Evicting the Hibernate Query Cache With Spring<h4>Goal</h4><br />This tutorial builds on the example presented in <a href="http://timezra.blogspot.com/2009/05/evicting-hibernate-cache-with-spring.html">a previous post</a>. Here we will explore the difference between the Hibernate second-level cache and the standard query cache and how the two can be used in conjunction to reduce the number of database transactions in an application.<br /><br /><h4>The Hibernate Second-level Cache</h4><br />We will begin with a quick review of the behavior of the Hibernate second-level cache. The results displayed on the http://localhost:8080/timezra.blog.hibernate.cache/books.htm page should look familiar if you have coded along with the <a href="http://timezra.blogspot.com/2009/05/evicting-hibernate-cache-with-spring.html">hibernate cache eviction example</a>.<br /><br />We can pick right up where we left off and update our sample book.<br /><div style="overflow:auto;width:60%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /> psql -U hibernate_cache -d hibernate_cache<br /> Update book Set subtitle = 'A Problem-Solution Approach' Where isbn_13 = 9781590599792;<br /></div><br /><br />After we follow the link for <em>Spring Recipes</em>, we will see that the subtitle of the book has not been updated. As demonstrated in the <a href="http://timezra.blogspot.com/2009/05/evicting-hibernate-cache-with-spring.html">previous post</a>, the query is persisting the individual <em>Book</em>s in the second-level cache, so this result should not surprise us.<br /><br />If we reopen or refresh <em>books.htm</em> and follow the link for <em>Spring Recipes</em> again, the subtitle of the book reflects the current state of the database. This result should raise an eyebrow. It appears that the transaction to find all the books has been re-run in the database and Hibernate has updated the individual items from the query's result in the second-level cache. Even though Hibernate stores individual <em>Book</em>s, it does not store the result of the query itself, so all the <em>Book</em>s are reloaded and persisted again.<br /><br /><h4>Cache the Query Results</h4><br />Caching individual domain objects has eliminated some unneccessary database traffic, but in this situation, we can optimize even more. Our database is updated exactly once at night, so we should not need a new transaction every time a user views the list of books.<br />In the Hibernate properties of <em>application-context-daos.xml</em>, we will enable the query cache.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;">....<br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernateProperties"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">props</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.cache.use_query_cache"</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">props</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br />....<br /></span><br /></div><br /><br />We must also configure <em>Book</em>'s <em>@NamedQuery</em> "findAllBooks" to store its results in the standard query cache.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /><span style="color: rgb(0,0,0);">....</span><br /><span style="color: rgb(0,0,0);">@NamedQueries(</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">@NamedQuery(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"findAllBooks"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">query</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"from Book"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">hints</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(0,0,0);">@javax.persistence.QueryHint(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"org.hibernate.cacheable"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">value</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"true"</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">}),</span><br /> <span style="color: rgb(0,0,0);">@NamedQuery(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"findByIsbn13"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">query</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"from Book book where book.isbn13 = :vIsbn13"</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">})</span><br /><span style="color: rgb(0,0,0);">....</span></span><br /></div><br /><br /><b>NB</b>: Rather than naming our queries with the <em>javax.persistence</em> annotations, we could just as well have used <em>org.hibernate.annotations</em>, in which case our declaration would not require <em>@QueryHints</em>.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /><span style="color: rgb(0,0,0);">....</span><br /><span style="color: rgb(0,0,0);">@org.hibernate.annotations.NamedQueries(</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">@org.hibernate.annotations.NamedQuery(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"findAllBooks"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">query</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"from Book"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">cacheable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">),</span><br /> <span style="color: rgb(0,0,0);">@org.hibernate.annotations.NamedQuery(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"findByIsbn13"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">query</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"from Book book where book.isbn13 = :vIsbn13"</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">})</span><br /><span style="color: rgb(0,0,0);">....</span></span><br /></div><br /><br /><b>NB</b>: Rather than configuring the <em>@NamedQuery</em> with <em>@QueryHints</em>, we could also enable caching in the <em>BookDAO</em> invocation of the query itself.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /> <span style="color: rgb(0,0,0);">....</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Collection<Book></span> <span style="color: rgb(0,0,0);">findAll()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession()</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.getNamedQuery(</span><span style="color: rgb(42,0,255);">"findAllBooks"</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.setCacheable(</span><span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.list();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">....</span></span><br /></div><br /><br />With any of these configurations, we can again run our test in the browser.<br /><ul><li>view all the books</li><li>select a single book</li><li>update the book in the database</li><li>view all the books again</li><li>select the same individual book</li></ul><br />The book now does not reflect the most current state of the database and clearly comes from the cache. This is the behavior that we are seeking.<br /><br /><h4>Flush the Query Cache</h4><br />From the <a href="http://timezra.blogspot.com/2009/05/evicting-hibernate-cache-with-spring.html">previous tutorial</a>, our Hibernate second-level cache is cleared every minute on the zeroth second. If we run the tests described above and wait long enough, we will eventually see an update to the book's subtitle. Suppose, however, we delete a book from the database.<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /> Delete From book Where isbn_13 = 9781590599792;<br /></div><br /><br />If we allow the second-level cache to expire and refresh the list of all books, we will see an error.<br /><div style="overflow:auto;width:100%; height:500px;padding:5px;color:red;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /><span style="color: rgb(42,0,255);text-decoration:underline;">org.hibernate.ObjectNotFoundException</span>: No row with the given identifier exists: [timezra.blog.hibernate.cache.domain.Book#9781590599792]<br /> at org.hibernate.impl.SessionFactoryImpl$2.handleEntityNotFound(<span style="color: rgb(42,0,255);text-decoration:underline;">SessionFactoryImpl.java:409</span>)<br /> at org.hibernate.event.def.DefaultLoadEventListener.load(<span style="color: rgb(42,0,255);text-decoration:underline;">DefaultLoadEventListener.java:171</span>)<br /> at org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(<span style="color: rgb(42,0,255);text-decoration:underline;">DefaultLoadEventListener.java:223</span>)<br /> at org.hibernate.event.def.DefaultLoadEventListener.onLoad(<span style="color: rgb(42,0,255);text-decoration:underline;">DefaultLoadEventListener.java:126</span>)<br /> at org.hibernate.impl.SessionImpl.fireLoad(<span style="color: rgb(42,0,255);text-decoration:underline;">SessionImpl.java:905</span>)<br /> at org.hibernate.impl.SessionImpl.internalLoad(<span style="color: rgb(42,0,255);text-decoration:underline;">SessionImpl.java:873</span>)<br /> at org.hibernate.type.EntityType.resolveIdentifier(<span style="color: rgb(42,0,255);text-decoration:underline;">EntityType.java:590</span>)<br /> at org.hibernate.type.ManyToOneType.assemble(<span style="color: rgb(42,0,255);text-decoration:underline;">ManyToOneType.java:219</span>)<br /> at org.hibernate.cache.StandardQueryCache.get(<span style="color: rgb(42,0,255);text-decoration:underline;">StandardQueryCache.java:155</span>)<br /> at org.hibernate.loader.Loader.getResultFromQueryCache(<span style="color: rgb(42,0,255);text-decoration:underline;">Loader.java:2184</span>)<br /> at org.hibernate.loader.Loader.listUsingQueryCache(<span style="color: rgb(42,0,255);text-decoration:underline;">Loader.java:2147</span>)<br /> at org.hibernate.loader.Loader.list(<span style="color: rgb(42,0,255);text-decoration:underline;">Loader.java:2117</span>)<br /> at org.hibernate.loader.hql.QueryLoader.list(<span style="color: rgb(42,0,255);text-decoration:underline;">QueryLoader.java:401</span>)<br /> at org.hibernate.hql.ast.QueryTranslatorImpl.list(<span style="color: rgb(42,0,255);text-decoration:underline;">QueryTranslatorImpl.java:361</span>)<br /> at org.hibernate.engine.query.HQLQueryPlan.performList(<span style="color: rgb(42,0,255);text-decoration:underline;">HQLQueryPlan.java:196</span>)<br /> at org.hibernate.impl.SessionImpl.list(<span style="color: rgb(42,0,255);text-decoration:underline;">SessionImpl.java:1148</span>)<br /> at org.hibernate.impl.QueryImpl.list(<span style="color: rgb(42,0,255);text-decoration:underline;">QueryImpl.java:102</span>)<br /> at timezra.blog.hibernate.cache.dao.BookDAO.findAll(<span style="color: rgb(42,0,255);text-decoration:underline;">BookDAO.java:25</span>)<br /> at sun.reflect.GeneratedMethodAccessor23.invoke(Unknown Source)<br /> at sun.reflect.DelegatingMethodAccessorImpl.invoke(<span style="color: rgb(42,0,255);text-decoration:underline;">DelegatingMethodAccessorImpl.java:25</span>)<br /> at java.lang.reflect.Method.invoke(<span style="color: rgb(42,0,255);text-decoration:underline;">Method.java:597</span>)<br /> at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(<span style="color: rgb(42,0,255);text-decoration:underline;">AopUtils.java:307</span>)<br /> at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(<span style="color: rgb(42,0,255);text-decoration:underline;">ReflectiveMethodInvocation.java:183</span>)<br /> at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(<span style="color: rgb(42,0,255);text-decoration:underline;">ReflectiveMethodInvocation.java:150</span>)<br /> at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(<span style="color: rgb(42,0,255);text-decoration:underline;">TransactionInterceptor.java:106</span>)<br /> at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(<span style="color: rgb(42,0,255);text-decoration:underline;">ReflectiveMethodInvocation.java:172</span>)<br /> at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(<span style="color: rgb(42,0,255);text-decoration:underline;">JdkDynamicAopProxy.java:202</span>)<br /> at $Proxy31.findAll(Unknown Source)<br /> at timezra.blog.hibernate.cache.controller.Books.showAllBooks(<span style="color: rgb(42,0,255);text-decoration:underline;">Books.java:24</span>)<br />....(more)<br /></span><br /></div><br />The persisted query results now reference the primary key for an invalid row that cannot be refreshed. Of course, since the query cache expires every 120 seconds per the default configuration in <em>ehcache.xml</em>, if we wait another minute, the error will no longer appear and we will simply see an empty table of books.<br /><br />In order to avoid these types of stale or non-existent results, we can modify <em>EvictTheSecondLevelCache.java</em> to flush the standard query cache.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,0,0);">....</span><br /> <span style="color: rgb(0,0,0);">@Override</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">protected</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">executeInternal(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">JobExecutionContext</span> <span style="color: rgb(0,0,0);">context)</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">JobExecutionException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">sessionFactory.evictQueries();</span><br /> <span style="color: rgb(0,0,0);">sessionFactory.evict(Book.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">....</span></span><br /></div><br /><b>NB</b>: We have chosen to evict the query cache before the second-level cache. If the two lines were reversed, we would still run the risk, however small, of encountering the <em>org.hibernate.ObjectNotFoundException</em> described above.<br /><br />Here we are evicting all queries in the default <em>org.hibernate.cache.StandardQueryCache</em>. If we want to be selective about the cached queries that should be flushed, <em>SessionFactory#sessionFactory.evictQueries(...)</em> also takes the name of a cache region, which we can declare as a <em>@QueryHint</em> in <em>Book.java</em> just as we have configured cacheability (or we could set another attribute on the <em>@org.hibernate.annotations.NamedQuery</em>, or we could set the cache region when the query is called directly in the <em>BookDAO</em>).<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,0,0);">....</span><br /><span style="color: rgb(0,0,0);">@NamedQueries(</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">@NamedQuery(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"findAllBooks"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">query</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"from Book"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">hints</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">@javax.persistence.QueryHint(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"org.hibernate.cacheable"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">value</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"true"</span><span style="color: rgb(0,0,0);">),</span><br /> <span style="color: rgb(0,0,0);">@javax.persistence.QueryHint(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"org.hibernate.cacheRegion"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">value</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"findAllBooks"</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">}),</span><br /> <span style="color: rgb(0,0,0);">@NamedQuery(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"findByIsbn13"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">query</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"from Book book where book.isbn13 = :vIsbn13"</span><br /> <span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">})</span><br /><span style="color: rgb(0,0,0);">....</span></span><br /></div><br /><br /><h4>Cache the Query But Not the Domain</h4><br />We now have three configurations for the two caches:<br /><ul><li>neither cache is enabled</li><li>only the second-level cache is enabled</li><li>both caches are enabled</li></ul><br />What is the result if we enable the standard query cache without storing domain objects?<br />We can explore this scenario by simply removing the query hint from the <em>@NamedQuery</em> to disable the domain store. We will then insert a record into the database.<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /> Insert Into book (author, title, isbn_13) Values ('Craig Walls', 'Spring in Action', 9781933988139);<br /></div><br /><br />After we view all the books in a browser, we will update the record.<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /> Update book Set title = 'Sprig in Acton' Where isbn_13 = 9781933988139;<br /></div><br /><br />The new title appears on the refreshed <em>books.htm</em> page. Even though Hibernate has stored the query results, because it has not saved the domain objects themselves, they have been refreshed by their primary keys from the database. Our particular set of books is rather small, but suppose we have a larger data set. The first time the query to find all books runs, there is exactly one transaction. For subsequent requests, until the query cache is cleared, Hibernate refreshes each <em>Book</em> individually by its ISBN. Clearly there is no performance benefit for us to cache only query results without domain objects in this scenario. In fact, this misconfiguration could cause a significant performance loss far worse than having no cache at all.<br /><br /><h4>Conclusion</h4><br />By expanding the infrastructure introduced in the <a href="http://timezra.blogspot.com/2009/05/evicting-hibernate-cache-with-spring.html">previous example</a>, we have further optimized our application's database transactions by caching not only individual objects, but also the result sets of queries. We can now also clear this store of query results at a fixed regular time coordinated with the eviction of the second-level cache.Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com3tag:blogger.com,1999:blog-106449775438946661.post-49834587948983410762009-05-22T18:03:00.000-07:002009-12-08T11:52:11.756-08:00Evicting the Hibernate Domain Cache With Spring<h4>Goal</h4><br />This tutorial presents an exploration of the <a href="https://www.hibernate.org/">Hibernate</a> second-level cache. By the end, we will have the tools to integrate <a href="http://ehcache.sourceforge.net/">Ehcache</a> into a web application and to expire its entries at fixed, regular intervals using the <a href="http://www.opensymphony.com/quartz/">Quartz scheduler</a> to run a <a href="http://static.springframework.org/spring-batch/">Spring batch</a> process.<br /><br /><h4>Setup a Database</h4><br />For this example, we can setup a PostgreSQL database, as in the <a href="http://timezra.blogspot.com/2009/05/mapping-hibernate-entities-to-views.html">previous example</a>. Here, our database, user and password can all be set to <em>hibernate_cache</em>.<br /><div style="overflow:auto;width:60%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /> psql -U postgres -c "CREATE DATABASE hibernate_cache" -d template1<br /> psql -U postgres -c "CREATE USER hibernate_cache WITH PASSWORD 'hibernate_cache'" -d hibernate_cache<br /> psql -U postgres -c "grant all privileges on database hibernate_cache to hibernate_cache" -d hibernate_cache<br /></span><br /></div><br /><br /><h4>A Maven2 Web Application</h4><br />We can create our <em>timezra.blog.hibernate.cache</em> project with the m2eclipse plugin. Instead of setting up a simple project as in a <a href="http://timezra.blogspot.com/2009/03/spring-30-quartz-batch-with-maven2.html">previous post</a>, we will use the <em>maven-archetype-webapp</em> from the Nexus Indexer catalog. We will also add <em>src/main/java</em>, <em>src/test/resources</em> and <em>src/test/java</em> explicitly to our build path since we naturally want to test our project as we add features incrementally. For web applications, <a href="http://docs.codehaus.org/display/JETTY/Maven+Jetty+Plugin">Jetty</a> provides a Maven plugin that scans our target path and automatically re-deploys any changes. The Jetty plugin can be configured in the <build> section of our <em>pom.xml</em>.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project....</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.mortbay.jetty<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>maven-jetty-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scanIntervalSeconds</span><span style="color: rgb(0,128,128);">></span>5<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scanIntervalSeconds</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">reload</span><span style="color: rgb(0,128,128);">></span>automatic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">reload</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br />We can start Jetty from a command prompt.<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /> mvn jetty:run<br /></span><br /></div><br />The page http://localhost:8080/timezra.blog.hibernate.cache/ will be available through a browser and we should see a "Hello World!" message.<br /><br /><h4>A Core Sample from the Database to the UI</h4><br />We are now ready to add Hibernate, Ehcache, Spring, Quartz and test-related dependencies. Our fully-configured <em>pom.xml</em> should look familiar to anyone who has gone through both the <a href="http://timezra.blogspot.com/2009/03/spring-30-quartz-batch-with-maven2.html">batch processing</a> and <a href="http://timezra.blogspot.com/2009/04/data-modelling-with-hibernate.html">Hibernate</a> tutorials, with a few additions specifically for web development and for emitting Java6-compliant code from our compiler during the build.<br /><div style="overflow:auto;width:100%;height:750px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0"</span> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span><br /> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span>4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>timezra.blog.hibernate.cache<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>timezra.blog.hibernate.cache<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">packaging</span><span style="color: rgb(0,128,128);">></span>war<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">packaging</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>0.0.1-SNAPSHOT<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span>timezra.blog.hibernate.cache Maven Webapp<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://maven.apache.org<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>org.springframework.context<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.0.M3<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>org.springframework.context.support<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.0.M3<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>org.springframework.web.servlet<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.0.M3<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>org.springframework.transaction<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.0.M3<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>org.springframework.orm<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.0.M3<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.hibernate<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>hibernate-annotations<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.4.0.GA<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.slf4j<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>slf4j-log4j12<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.5.2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>javassist<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>javassist<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.4.GA<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>cglib<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>cglib<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>commons-collections<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>commons-collections<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.2.1<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>commons-dbcp<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>commons-dbcp<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.2.2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>net.sf.ehcache<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>ehcache<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.5.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.opensymphony.quartz<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>quartz<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.6.1<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>postgresql<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>postgresql<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>8.3-603.jdbc4<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>javax.servlet<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>servlet-api<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.5<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>junit<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>junit<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>4.5<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>org.springframework.test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.0.M3<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">finalName</span><span style="color: rgb(0,128,128);">></span>timezra.blog.hibernate.cache<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">finalName</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.apache.maven.plugins<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>maven-compiler-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">source</span><span style="color: rgb(0,128,128);">></span>1.6<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">source</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">target</span><span style="color: rgb(0,128,128);">></span>1.6<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">target</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.mortbay.jetty<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>maven-jetty-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scanIntervalSeconds</span><span style="color: rgb(0,128,128);">></span>5<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scanIntervalSeconds</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">reload</span><span style="color: rgb(0,128,128);">></span>automatic<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">reload</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repositories</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>SpringSource Enterprise Bundle Repository - External Bundle Milestones<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://repository.springsource.com/maven/bundles/milestone<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://repository.springsource.com/maven/bundles/release<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>SpringSource Enterprise Bundle Repository - External Bundle Releases<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://repository.springsource.com/maven/bundles/external<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repositories</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br />Since we will be using Spring MVC for our web framework, we must configure the <em>src/main/webapp/WEB-INF/web.xml</em> to route all page requests with an <em>htm</em> extension through the Spring <a href="http://java.sun.com/blueprints/patterns/FrontController.html">Front Controller</a>.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">web-app</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"2.4"</span> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://java.sun.com/xml/ns/j2ee"</span><br /> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span><br /> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://java.sun.com/xml/ns/j2ee <br /> http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">display-name</span><span style="color: rgb(0,128,128);">></span>Archetype Created Web Application<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">display-name</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">servlet</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">servlet-name</span><span style="color: rgb(0,128,128);">></span>timezra.blog.hibernate.cache<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">servlet-name</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">servlet-class</span><span style="color: rgb(0,128,128);">></span>org.springframework.web.servlet.DispatcherServlet<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">servlet-class</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">load-on-startup</span><span style="color: rgb(0,128,128);">></span>1<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">load-on-startup</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">servlet</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">servlet-mapping</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">servlet-name</span><span style="color: rgb(0,128,128);">></span>timezra.blog.hibernate.cache<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">servlet-name</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url-pattern</span><span style="color: rgb(0,128,128);">></span>*.htm<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url-pattern</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">servlet-mapping</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">web-app</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br />We must not necessarily declare the application <em>contextConfigLocation</em> in the <em>web.xml</em> since the Spring MVC convention of locating a file with the servlet name and a <em>-servlet.xml</em> suffix will suffice. Our <em>src/main/webapp/WEB-INF/timezra.blog.hibernate.cache-servlet.xml</em> can simply indicate where the view pages will reside.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">beans</span> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/beans"</span><br /> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span> <br /> <span style="color: rgb(127,0,127);">xmlns:context</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/context"</span><br /> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/beans<br /> http://www.springframework.org/schema/beans/spring-beans.xsd<br /> http://www.springframework.org/schema/context<br /> http://www.springframework.org/schema/context/spring-context.xsd"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"viewResolver"</span><br /> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.web.servlet.view.InternalResourceViewResolver"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"viewClass"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.web.servlet.view.JstlView"</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"prefix"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"/WEB-INF/jsp/"</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"suffix"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">".jsp"</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">beans</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><br />Suppose we have the following user story:<br /><div style="overflow:auto;width:50%;padding:10px;background-color:yellow;border-style:double;border-width:1px"><br /><span style="font-weight: bold; color: rgb(127,0,85);">As a</span> customer,<br /><span style="font-weight: bold; color: rgb(127,0,85);">I want</span> to browse through a list of titles,<br /><span style="font-weight: bold; color: rgb(127,0,85);">So that</span> I can find out who wrote a particular book.<br /></div><br /><br />We can interact with our domain through a data access component, an <em>IBookDAO</em> that has two functions: one for retrieving all the books, and another for retrieving a single book based on its key.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.cache.dao;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Collection;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.cache.domain.Book;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">interface</span> <span style="color: rgb(0,0,0);">IBookDAO</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">Collection<Book></span> <span style="color: rgb(0,0,0);">findAll();</span><br /> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">findByIsbn13(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">isbn13);</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br />Our domain needs just one object, a <em>Book</em>, and it will have attributes for the title, author and a unique value for the primary key, which here can be an isbn. We can also specify the HQL queries for accessing this object.<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.cache.domain;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Column;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Entity;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Id;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.NamedQueries;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.NamedQuery;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Table;</span><br /><br /><span style="color: rgb(0,0,0);">@Entity</span><br /><span style="color: rgb(0,0,0);">@Table(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"BOOK"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">schema</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">""</span><span style="color: rgb(0,0,0);">)</span><br /><span style="color: rgb(0,0,0);">@NamedQueries(</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(0,0,0);">@NamedQuery(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"findAllBooks"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">query</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"from Book"</span><span style="color: rgb(0,0,0);">),</span><br /> <span style="color: rgb(0,0,0);">@NamedQuery(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"findByIsbn13"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">query</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"from Book book where book.isbn13 = :vIsbn13"</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">})</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">Book</span> <span style="font-weight: bold; color: rgb(127,0,85);">implements</span> <span style="color: rgb(0,0,0);">java.io.Serializable</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">serialVersionUID</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">7081749995516354985L;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">isbn13;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">title;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">subtitle;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">author;</span><br /><br /> <span style="color: rgb(0,0,0);">@Id</span><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"ISBN_13"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">getIsbn13()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">isbn13;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setIsbn13(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">isbn13)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.isbn13</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">isbn13;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"TITLE"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">50)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getTitle()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">title;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setTitle(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">title)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.title</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">title;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"SUBTITLE"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">150)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getSubtitle()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">subtitle;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setSubtitle(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">subtitle)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.subtitle</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">subtitle;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"AUTHOR"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">50)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getAuthor()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">author;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setAuthor(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">author)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.author</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">author;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span></span><br /></div><br /><br />In the <em>src/main/resources/hibernate.cfg.xml</em>, we will register the <em>Book</em>.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><!</span><span style="color: rgb(63,127,127);">DOCTYPE</span> <span style="color: rgb(0,128,128);">hibernate-configuration</span> <span style="color: rgb(128,128,128);">PUBLIC</span><br /> <span style="color: rgb(0,128,128);">"-//Hibernate/Hibernate Configuration DTD 3.0//EN"</span><br /> <span style="color: rgb(63,127,95);">"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">hibernate-configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">session-factory</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">mapping</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"timezra.blog.hibernate.cache.domain.Book"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">session-factory</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">hibernate-configuration</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><br /><br />Our <em>BookDAO</em> can simply use the <em>@NamedQueries</em> declared on <em>Book</em> to implement its functions.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.cache.dao;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Collection;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.SessionFactory;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.beans.factory.annotation.Autowired;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.stereotype.Repository;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.transaction.annotation.Transactional;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.cache.domain.Book;</span><br /><br /><span style="color: rgb(0,0,0);">@Repository</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">BookDAO</span> <span style="font-weight: bold; color: rgb(127,0,85);">implements</span> <span style="color: rgb(0,0,0);">IBookDAO</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">SessionFactory</span> <span style="color: rgb(0,0,0);">sessionFactory;</span><br /><br /> <span style="color: rgb(0,0,0);">@Autowired</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">BookDAO(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">SessionFactory</span> <span style="color: rgb(0,0,0);">sessionFactory)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.sessionFactory</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">sessionFactory;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@SuppressWarnings(</span><span style="color: rgb(42,0,255);">"unchecked"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@Transactional</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Collection<Book></span> <span style="color: rgb(0,0,0);">findAll()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession()</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.getNamedQuery(</span><span style="color: rgb(42,0,255);">"findAllBooks"</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.list();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Transactional</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">findByIsbn13(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">isbn13)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">(Book)</span> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession()</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.getNamedQuery(</span><span style="color: rgb(42,0,255);">"findByIsbn13"</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.setParameter(</span><span style="color: rgb(42,0,255);">"vIsbn13"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">isbn13)</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.uniqueResult();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><b>NB</b>: We have annotated the DAO as a <em>@Repository</em>. Instead of declaring this Spring bean explicitly, we merely need to configure Spring to scan a set of packages to discover the components to use as beans.<br /><br />Because the web application context is outside the classpath, we can delegate Spring registration of our DAOs to a classpath resource. We will import the <em>application-context-daos.xml</em> in the <em>timezra.blog.hibernate.cache-servlet.xml</em>.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;">....<br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">beans....</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">import</span> <span style="color: rgb(127,0,127);">resource</span>=<span style="font-style: italic; color: rgb(42,0,255);">"classpath:application-context-daos.xml"</span><span style="color: rgb(0,128,128);">/></span><br /> ....<br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">beans</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><br />The <em>src/main/resources/application-context-daos.xml</em> file contains the database connection configuration.<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">beans</span> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/beans"</span><br /> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span> <br /> <span style="color: rgb(127,0,127);">xmlns:tx</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/tx"</span><br /> <span style="color: rgb(127,0,127);">xmlns:context</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/context"</span><br /> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/beans<br /> http://www.springframework.org/schema/beans/spring-beans.xsd<br /> http://www.springframework.org/schema/context<br /> http://www.springframework.org/schema/context/spring-context.xsd<br /> http://www.springframework.org/schema/tx<br /> http://www.springframework.org/schema/tx/spring-tx.xsd"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"dataSource"</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.apache.commons.dbcp.BasicDataSource"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"driverClassName"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span>org.postgresql.Driver<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"username"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span>hibernate_cache<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"password"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span>hibernate_cache<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"url"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span>jdbc:postgresql://localhost:5432/hibernate_cache<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"sessionFactory"</span><br /> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.orm.hibernate3.LocalSessionFactoryBean"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"dataSource"</span> <span style="color: rgb(127,0,127);">ref</span>=<span style="font-style: italic; color: rgb(42,0,255);">"dataSource"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"configLocation"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"classpath:hibernate.cfg.xml"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"configurationClass"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.hibernate.cfg.AnnotationConfiguration"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernateProperties"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">props</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.show_sql"</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.format_sql"</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.generate_statistics"</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.use_sql_comments"</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.hbm2ddl.auto"</span><span style="color: rgb(0,128,128);">></span>update<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.dialect"</span><span style="color: rgb(0,128,128);">></span>org.hibernate.dialect.PostgreSQLDialect<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.query.factory_class"</span><span style="color: rgb(0,128,128);">></span>org.hibernate.hql.ast.ASTQueryTranslatorFactory<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">props</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">context:component-scan</span> <span style="color: rgb(127,0,127);">base-package</span>=<span style="font-style: italic; color: rgb(42,0,255);">"timezra.blog.hibernate.cache.dao"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"txManager"</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.orm.hibernate3.HibernateTransactionManager"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"sessionFactory"</span> <span style="color: rgb(127,0,127);">ref</span>=<span style="font-style: italic; color: rgb(42,0,255);">"sessionFactory"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">tx:annotation-driven</span> <span style="color: rgb(127,0,127);">transaction-manager</span>=<span style="font-style: italic; color: rgb(42,0,255);">"txManager"</span> <span style="color: rgb(0,128,128);">/></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">beans</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><b>NB</b>: We have not declared our DAO explicitly because we have configured Spring to scan for components in the package that contains our <em>@Resource</em>.<br /><br />Now that we have a domain and a way to access the domain, we can write some tests in the <em>BookDAOTest</em> suite to ensure that our functions work. <br /><div style="overflow:auto;width:100%;height:750px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.cache.dao;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">org.junit.Assert.assertSame;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">org.junit.Assert.assertTrue;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Collection;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.Session;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.SessionFactory;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.Before;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.Test;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.runner.RunWith;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.beans.factory.annotation.Autowired;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.ContextConfiguration;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.junit4.SpringJUnit4ClassRunner;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.transaction.TransactionConfiguration;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.transaction.annotation.Transactional;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.cache.domain.Book;</span><br /><br /><span style="color: rgb(0,0,0);">@RunWith(SpringJUnit4ClassRunner.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">)</span><br /><span style="color: rgb(0,0,0);">@ContextConfiguration(locations</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(42,0,255);">"/application-context-daos.xml"</span> <span style="color: rgb(0,0,0);">})</span><br /><span style="color: rgb(0,0,0);">@TransactionConfiguration(transactionManager</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"txManager"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">defaultRollback</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">)</span><br /><span style="color: rgb(0,0,0);">@Transactional</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">BookDAOTest</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="color: rgb(0,0,0);">@Autowired</span> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">SessionFactory</span> <span style="color: rgb(0,0,0);">sessionFactory;</span><br /> <span style="color: rgb(0,0,0);">@Autowired</span> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">IBookDAO</span> <span style="color: rgb(0,0,0);">bookDAO;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">hibernateMadeEasy;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">harnessingHibernate;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">javaPersistenceWithHibernate;</span><br /><br /> <span style="color: rgb(0,0,0);">@Before</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setUp()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Session</span> <span style="color: rgb(0,0,0);">session</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession();</span><br /> <span style="color: rgb(0,0,0);">session.save(getOrCreateHibernateMadeEasy());</span><br /> <span style="color: rgb(0,0,0);">session.save(getOrCreateJavaPersistenceWithHibernate());</span><br /> <span style="color: rgb(0,0,0);">session.save(getOrCreateHarnessingHibernate());</span><br /> <span style="color: rgb(0,0,0);">session.flush();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">findAllReturnsAllTheBooks()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Book></span> <span style="color: rgb(0,0,0);">books</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">bookDAO.findAll();</span><br /><br /> <span style="color: rgb(0,0,0);">assertTrue(books.contains(getOrCreateHibernateMadeEasy()));</span><br /> <span style="color: rgb(0,0,0);">assertTrue(books.contains(getOrCreateHarnessingHibernate()));</span><br /> <span style="color: rgb(0,0,0);">assertTrue(books.contains(getOrCreateJavaPersistenceWithHibernate()));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">findByIsbn13ReturnsTheBook()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">actual</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">bookDAO.findByIsbn13(9780596517724L);</span><br /> <span style="color: rgb(0,0,0);">assertSame(getOrCreateHarnessingHibernate(),</span> <span style="color: rgb(0,0,0);">actual);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">getOrCreateHibernateMadeEasy()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(hibernateMadeEasy</span> <span style="color: rgb(0,0,0);">!=</span> <span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">hibernateMadeEasy;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">hibernateMadeEasy</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Book();</span><br /> <span style="color: rgb(0,0,0);">hibernateMadeEasy.setAuthor(</span><span style="color: rgb(42,0,255);">"Cameron McKenzie"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">hibernateMadeEasy.setIsbn13(9780615201955L);</span><br /> <span style="color: rgb(0,0,0);">hibernateMadeEasy.setTitle(</span><span style="color: rgb(42,0,255);">"Hibernate Made Easy"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">hibernateMadeEasy</span><br /> <span style="color: rgb(0,0,0);">.setSubtitle(</span><span style="color: rgb(42,0,255);">"Simplified Data Persistence with Hibernate and JPA (Java Persistence API) Annotations"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">hibernateMadeEasy;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">getOrCreateHarnessingHibernate()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(harnessingHibernate</span> <span style="color: rgb(0,0,0);">!=</span> <span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">harnessingHibernate;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">harnessingHibernate</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Book();</span><br /> <span style="color: rgb(0,0,0);">harnessingHibernate.setAuthor(</span><span style="color: rgb(42,0,255);">"James Elliott"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">harnessingHibernate.setIsbn13(9780596517724L);</span><br /> <span style="color: rgb(0,0,0);">harnessingHibernate.setTitle(</span><span style="color: rgb(42,0,255);">"Harnessing Hibernate"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">harnessingHibernate;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">getOrCreateJavaPersistenceWithHibernate()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(javaPersistenceWithHibernate</span> <span style="color: rgb(0,0,0);">!=</span> <span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">javaPersistenceWithHibernate;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">javaPersistenceWithHibernate</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Book();</span><br /> <span style="color: rgb(0,0,0);">javaPersistenceWithHibernate.setAuthor(</span><span style="color: rgb(42,0,255);">"Christian Bauer"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">javaPersistenceWithHibernate.setIsbn13(9781932394887L);</span><br /> <span style="color: rgb(0,0,0);">javaPersistenceWithHibernate.setTitle(</span><span style="color: rgb(42,0,255);">"Java Persistence with Hibernate"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">javaPersistenceWithHibernate;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><b>NB</b>: Because the <em>application-context-daos.xml</em> is on the classpath, Spring will locate the context for the tests and inject the dependencies.<br /><br />Finally, we can create a view into the database for each of the functions of the user story. One controller called <em>Books</em> can handle both requests.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.cache.controller;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.servlet.http.HttpServletRequest;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.beans.factory.annotation.Autowired;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.stereotype.Controller;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.web.bind.annotation.RequestMapping;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.web.servlet.ModelAndView;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.cache.dao.IBookDAO;</span><br /><br /><span style="color: rgb(0,0,0);">@Controller</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">Books</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">IBookDAO</span> <span style="color: rgb(0,0,0);">bookDAO;</span><br /><br /> <span style="color: rgb(0,0,0);">@Autowired</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Books(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">IBookDAO</span> <span style="color: rgb(0,0,0);">bookDAO)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.bookDAO</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">bookDAO;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@RequestMapping(</span><span style="color: rgb(42,0,255);">"/books.htm"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">ModelAndView</span> <span style="color: rgb(0,0,0);">showAllBooks()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">ModelAndView(</span><span style="color: rgb(42,0,255);">"books"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">"books"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">bookDAO.findAll());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@RequestMapping(</span><span style="color: rgb(42,0,255);">"/book.htm"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">ModelAndView</span> <span style="color: rgb(0,0,0);">showABook(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">HttpServletRequest</span> <span style="color: rgb(0,0,0);">request)</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">ModelAndView(</span><span style="color: rgb(42,0,255);">"book"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">"book"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">bookDAO.findByIsbn13(Long.valueOf(request.getParameter(</span><span style="color: rgb(42,0,255);">"isbn13"</span><span style="color: rgb(0,0,0);">))));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br />Note how <em>Books</em> is registered as a <em>@Controller</em>, just as <em>BookDAO</em> is a <em>@Resource</em>. We will simply register the controller's package in our <em>timezra.blog.hibernate.cache-servlet.xml</em> and Spring will locate the component.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;">....<br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">beans....</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">context:component-scan</span> <span style="color: rgb(127,0,127);">base-package</span>=<span style="font-style: italic; color: rgb(42,0,255);">"timezra.blog.hibernate.cache.controller"</span><span style="color: rgb(0,128,128);">/></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">beans</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><br />The first request, which takes no parameters, provides a view of all the titles in the database. We can call this view <em>src/main/webapp/WEB-INF/jsp/books.jsp</em>.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span>%@ page language="java" contentType="text/html; charset=ISO-8859-1"<br /> pageEncoding="ISO-8859-1"<span style="color: rgb(0,0,0);">%</span>><br /><span style="color: rgb(0,128,128);"><</span>%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" <span style="color: rgb(0,0,0);">%</span>><br /><span style="color: rgb(0,128,128);"><!</span><span style="color: rgb(63,127,127);">DOCTYPE</span> <span style="color: rgb(0,128,128);">html</span> <span style="color: rgb(128,128,128);">PUBLIC</span> <span style="color: rgb(0,128,128);">"-//W3C//DTD HTML 4.01 Transitional//EN"</span> <span style="color: rgb(63,127,95);">"http://www.w3.org/TR/html4/loose.dtd"</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">html</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">head</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">meta</span> <span style="color: rgb(127,0,127);">http-equiv</span>=<span style="font-style: italic; color: rgb(42,0,255);">"Content-Type"</span> <span style="color: rgb(127,0,127);">content</span>=<span style="font-style: italic; color: rgb(42,0,255);">"text/html; charset=ISO-8859-1"</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">title</span><span style="color: rgb(0,128,128);">></span>All The Books<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">title</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">head</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">body</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">h1</span><span style="color: rgb(0,128,128);">></span>All The Books<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">h1</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">table</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">tr</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">th</span><span style="color: rgb(0,128,128);">></span>ISBN 13<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">th</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">th</span><span style="color: rgb(0,128,128);">></span>Title<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">th</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">tr</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">c:forEach</span> <span style="color: rgb(127,0,127);">items</span>=<span style="font-style: italic; color: rgb(42,0,255);">"${books}"</span> <span style="color: rgb(127,0,127);">var</span>=<span style="font-style: italic; color: rgb(42,0,255);">"book"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">tr</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">td</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">a</span> <span style="color: rgb(127,0,127);">href</span>=<span style="font-style: italic; color: rgb(42,0,255);">"</span><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">c:url</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">'/book.htm'</span><span style="color: rgb(0,128,128);">/></span>?isbn13=<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">c:out</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">'${book.isbn13}'</span> <span style="color: rgb(0,128,128);">/></span>"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">c:out</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"${book.isbn13}"</span> <span style="color: rgb(0,128,128);">/></span><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">a</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">td</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">td</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">c:out</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"${book.title}"</span> <span style="color: rgb(0,128,128);">/></span><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">td</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">tr</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">c:forEach</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">table</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">body</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">html</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><br />The second request provides a view of the details of a single book, which is located by its isbn-13. This view is <em>src/main/webapp/WEB-INF/jsp/book.jsp</em>.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span>%@ page language="java" contentType="text/html; charset=ISO-8859-1"<br /> pageEncoding="ISO-8859-1"<span style="color: rgb(0,0,0);">%</span>><br /><span style="color: rgb(0,128,128);"><</span>%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" <span style="color: rgb(0,0,0);">%</span>><br /><span style="color: rgb(0,128,128);"><!</span><span style="color: rgb(63,127,127);">DOCTYPE</span> <span style="color: rgb(0,128,128);">html</span> <span style="color: rgb(128,128,128);">PUBLIC</span> <span style="color: rgb(0,128,128);">"-//W3C//DTD HTML 4.01 Transitional//EN"</span> <span style="color: rgb(63,127,95);">"http://www.w3.org/TR/html4/loose.dtd"</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">html</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">head</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">meta</span> <span style="color: rgb(127,0,127);">http-equiv</span>=<span style="font-style: italic; color: rgb(42,0,255);">"Content-Type"</span> <span style="color: rgb(127,0,127);">content</span>=<span style="font-style: italic; color: rgb(42,0,255);">"text/html; charset=ISO-8859-1"</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">title</span><span style="color: rgb(0,128,128);">></span>A Book<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">title</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">head</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">body</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">h1</span><span style="color: rgb(0,128,128);">></span>${book.title}<span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">c:if</span> <span style="color: rgb(127,0,127);">test</span>=<span style="font-style: italic; color: rgb(42,0,255);">"${not empty book.subtitle}"</span><span style="color: rgb(0,128,128);">></span>:<span style="color: rgb(42,0,255);">&nbsp;</span><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">c:out</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"${book.subtitle}"</span> <span style="color: rgb(0,128,128);">/></span><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">c:if</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">h1</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">br</span><span style="color: rgb(0,128,128);">/></span><br /> Author: <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">c:out</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"${book.author}"</span> <span style="color: rgb(0,128,128);">/></span><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">br</span><span style="color: rgb(0,128,128);">/></span><br /> ISBN 13: <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">c:out</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"${book.isbn13}"</span> <span style="color: rgb(0,128,128);">/></span><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">br</span><span style="color: rgb(0,128,128);">/></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">body</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">html</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><br />The page http://localhost:8080/timezra.blog.hibernate.cache/books.htm will be available through a browser and should display an empty table of information. If we were to begin adding books to our database, we would see this table fill and we could navigate to individual book detail pages.<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /> psql -U hibernate_cache -d hibernate_cache<br /> Insert Into book (author, subtitle, title, isbn_13)<br /> values ('Gary Mak', 'A Problem-Solution Approach (Books for Professionals by Professionals)', 'Spring Recipes', 9781590599792);<br /></span><br /></div><br /><br /><h4>Cache For Books</h4><br />Suppose an external process updates our database of books once nightly, but we expect that customers will browse for books frequently during the day. To reduce database overhead, we can cache the book information on the application server. We will expire the cache only after the database has been updated.<br /><br />The Hibernate primary cache is used automatically for transaction-level optimization. Therefore, a domain object should only be retrieved once for each full database transaction, even if it is referenced more than once. <br />Hibernate second-level persistence, by contrast, is SessionFactory-wide, so the information about the object is available across multiple transactions. This second-level store is not automatic and must be explicitly configured. We can register the <em>Book</em> as a candidate for such a cache with a class-level annotation.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,0,0);">....</span><br /><span style="color: rgb(0,0,0);">@org.hibernate.annotations.Cache(usage</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">org.hibernate.annotations.CacheConcurrencyStrategy.</span><span style="color: rgb(42,0,255);">READ_ONLY</span>)<br /><span style="color: rgb(0,0,0);">....</span></span><br /></div><br /><br />For this example, we will use Ehcache, which requires an external configuration, here called <em>src/main/resources/ehcache.xml</em>. We will declare default settings as well as properties for individual domain objects. We can store the <em>Book</em>s forever because we will expire the cache periodically through a batch process.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">ehcache</span> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span><br /> <span style="color: rgb(127,0,127);">xsi:noNamespaceSchemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"ehcache.xsd"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">diskStore</span> <span style="color: rgb(127,0,127);">path</span>=<span style="font-style: italic; color: rgb(42,0,255);">"java.io.tmpdir"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">defaultCache</span> <br /> <span style="color: rgb(127,0,127);">maxElementsInMemory</span>=<span style="font-style: italic; color: rgb(42,0,255);">"10000"</span> <br /> <span style="color: rgb(127,0,127);">eternal</span>=<span style="font-style: italic; color: rgb(42,0,255);">"false"</span><br /> <span style="color: rgb(127,0,127);">timeToIdleSeconds</span>=<span style="font-style: italic; color: rgb(42,0,255);">"120"</span> <br /> <span style="color: rgb(127,0,127);">timeToLiveSeconds</span>=<span style="font-style: italic; color: rgb(42,0,255);">"120"</span> <br /> <span style="color: rgb(127,0,127);">overflowToDisk</span>=<span style="font-style: italic; color: rgb(42,0,255);">"true"</span><br /> <span style="color: rgb(127,0,127);">diskPersistent</span>=<span style="font-style: italic; color: rgb(42,0,255);">"false"</span> <br /> <span style="color: rgb(127,0,127);">diskExpiryThreadIntervalSeconds</span>=<span style="font-style: italic; color: rgb(42,0,255);">"120"</span><br /> <span style="color: rgb(127,0,127);">memoryStoreEvictionPolicy</span>=<span style="font-style: italic; color: rgb(42,0,255);">"LRU"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">cache</span> <br /> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"timezra.blog.hibernate.cache.domain.Book"</span><br /> <span style="color: rgb(127,0,127);">maxElementsInMemory</span>=<span style="font-style: italic; color: rgb(42,0,255);">"100"</span> <br /> <span style="color: rgb(127,0,127);">eternal</span>=<span style="font-style: italic; color: rgb(42,0,255);">"true"</span> <br /> <span style="color: rgb(127,0,127);">overflowToDisk</span>=<span style="font-style: italic; color: rgb(42,0,255);">"false"</span> <span style="color: rgb(0,128,128);">/></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">ehcache</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><br />Finally, we can update the Hibernate properties in the <em>application-context-daos.xml</em>. <br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;">....<br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernateProperties"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">props</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.cache.provider_class"</span><span style="color: rgb(0,128,128);">></span>net.sf.ehcache.hibernate.SingletonEhCacheProvider<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.cache.use_second_level_cache"</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.cache.provider_configuration"</span><span style="color: rgb(0,128,128);">></span>classpath:ehcache.xml<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">props</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br />....</span><br /></div><br /><br />Now, we will view our book through the browser. None of the information will have changed, as expected.<br /><br />Suppose we update the book through psql.<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /> Update book Set author = 'Mak, Gary' Where isbn_13 = 9781590599792;<br /></span><br /></div><br /><br />Now that the second-level cache is available and our domain object has been registered, I would expect that the information on the page will not have changed. When we refresh the browser, however, the author's name is updated. This indicates that, even though the <em>@NamedQuery</em> uses HQL and the query does a lookup by the <em>Book</em>'s primary key, the result is not taken from the second-level store, and a database transaction has occurred. The cache has provided no benefit.<br /><br />Suppose we change BookDAO#findByIsbn13(...) to query by criteria.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"> <span style="color: rgb(0,0,0);">....</span><br /> <span style="color: rgb(0,0,0);">@Transactional</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">findByIsbn13(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">isbn13)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">(Book)</span> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession()</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.createCriteria(Book.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.add(org.hibernate.criterion.Restrictions.eq(</span><span style="color: rgb(42,0,255);">"isbn13"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">isbn13))</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.uniqueResult();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">....</span></span><br /></div><br /><br />Again, we will view the book through the browser, and again we will modify the data.<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /> Update book Set author = 'Gary Mak' Where isbn_13 = 9781590599792;<br /></span><br /></div><br /><br />When we refresh the browser, the data will have changed to reflect the current state in the database. This behavior indicates that, despite very simple criteria, i.e., primary key equality, Hibernate is bypassing the store and directly querying the database.<br /><br />Suppose we change BookDAO#findByIsbn13(...) to get the <em>Book</em> directly from the current session.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"> <span style="color: rgb(0,0,0);">@Transactional</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">findByIsbn13(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">isbn13)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">(Book)</span> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession().get(Book.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">isbn13);</span><br /> <span style="color: rgb(0,0,0);">}</span></span><br /></div><br /><br />Finally, when we view the data in the browser, update the author through psql, and refresh the browser again, we will see the expected caching behavior.<br /><b>NB</b>: We also could have used SessionFactory#load(...), but this method returns a proxy to the actual <em>Book</em> instance. We would need to resolve this within a transactional context, e.g., by calling an accessor method for one of the non-primary-key fields in the DAO method. Also, even if the <em>Book</em> does not exist in the cache, #load(...) will return a proxy, and we will see an error when Hibernate tries to resolve it. For our needs, SessionFactory#get(...) is sufficient.<br /><br /><h4>Evict the Cache</h4><br />Now that our caching behavior works as anticipated, we will use a Spring batch process with a Quartz timer to evict the cache at a specific time. In this type of scenario, the job might run during a period of low traffic, perhaps in the middle of the night. For our example, we will expire the cache every minute for fast feedback.<br /><br />For anyone who has worked through the previous <a href="http://timezra.blogspot.com/2009/03/spring-30-quartz-batch-with-maven2.html">tutorial on Spring batch processing</a>, there should be no surprises in this code.<br />We will first create a job implementation, <em>EvictTheSecondLevelCache</em>, that removes all the <em>Book</em>s from the SessionFactory's store.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.cache.batch;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.SessionFactory;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.quartz.JobExecutionContext;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.quartz.JobExecutionException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.quartz.StatefulJob;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.scheduling.quartz.QuartzJobBean;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.cache.domain.Book;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">EvictTheSecondLevelCache</span> <span style="font-weight: bold; color: rgb(127,0,85);">extends</span> <span style="color: rgb(0,0,0);">QuartzJobBean</span> <span style="font-weight: bold; color: rgb(127,0,85);">implements</span> <span style="color: rgb(0,0,0);">StatefulJob</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">SessionFactory</span> <span style="color: rgb(0,0,0);">sessionFactory;</span><br /><br /> <span style="color: rgb(0,0,0);">@Override</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">protected</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">executeInternal(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">JobExecutionContext</span> <span style="color: rgb(0,0,0);">context)</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">JobExecutionException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">sessionFactory.evict(Book.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setSessionFactory(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">SessionFactory</span> <span style="color: rgb(0,0,0);">sessionFactory)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.sessionFactory</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">sessionFactory;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br />We can register and schedule the job with a new Spring context file, <em>src/main/resources/application-context-batch.xml</em>.<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">beans</span> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/beans"</span><br /> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span> <br /> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/beans<br /> http://www.springframework.org/schema/beans/spring-beans.xsd"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">import</span> <span style="color: rgb(127,0,127);">resource</span>=<span style="font-style: italic; color: rgb(42,0,255);">"classpath:application-context-daos.xml"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobDetail"</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.scheduling.quartz.JobDetailBean"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobClass"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"timezra.blog.hibernate.cache.batch.EvictTheSecondLevelCache"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobDataAsMap"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">map</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">entry</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"sessionFactory"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">ref</span> <span style="color: rgb(127,0,127);">bean</span>=<span style="font-style: italic; color: rgb(42,0,255);">"sessionFactory"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">entry</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">map</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobDetailTrigger"</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.scheduling.quartz.CronTriggerBean"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobDetail"</span> <span style="color: rgb(127,0,127);">ref</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobDetail"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"cronExpression"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"0 * * * * ?"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"schedulerFactoryBean"</span><br /> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.scheduling.quartz.SchedulerFactoryBean"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"triggers"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">list</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">ref</span> <span style="color: rgb(127,0,127);">bean</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobDetailTrigger"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">list</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">beans</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><b>NB</b>: To inject the <em>sessionFactory</em> declared in <em>application-context-daos.xml</em>, we must import that resource, as well.<br /><br />Finally, we will register the new configuration with the general web application context, <em>timezra.blog.hibernate.cache-servlet.xml</em>, so that the job begins automatically when the web application starts.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;">....<br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">beans....</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">import</span> <span style="color: rgb(127,0,127);">resource</span>=<span style="font-style: italic; color: rgb(42,0,255);">"classpath:application-context-batch.xml"</span><span style="color: rgb(0,128,128);">/></span><br /> ....<br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">beans</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><br />Now, we can load our book details in the browser, update the author through psql, reload the page, and the data should not have changed. If we wait until the cache is invalidated (here, one or two minutes) and refresh the page, the data will reflect the current state of the table.<br /><br /><h4>Conclusion</h4><br />With a few kilobytes of custom code, we have a project infrastructure for unit tests, a domain, a data access layer, views into our data, a batch process and a cache that will make expanding the application with more tests, a larger domain, more sophisticated queries, caching and page flows straightforward, at least from a technical perspective. Gathering user stories and prioritizing them by potential ROI is another topic entirely and one that must be handled as a conversation between you and your product owner.<br /><br /><img src="http://farm3.static.flickr.com/2422/3555647020_b381f5f70e_o.png" alt="The Maven2 standard webapp project structure." /><br /><br />Coming Soon: <a href="http://timezra.blogspot.com/2009/05/evicting-hibernate-query-cache-with.html">The Hibernate query cache. . . .</a>Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com4tag:blogger.com,1999:blog-106449775438946661.post-30972432351388524572009-05-13T19:38:00.000-07:002009-05-28T16:40:40.926-07:00Mapping Hibernate Entities to Views<h4>Goal</h4><br />By the end of this tutorial, we will have the tools to map a Hibernate Entity that does not correspond directly to a database table onto structures such as views or query results.<br /><br /><h4>Setup a PostgreSQL Database</h4><br />This tutorial breaks from the pattern of <a href="http://timezra.blogspot.com/2009/04/data-modelling-with-hibernate.html">previous posts in this series</a> by using PostgreSQL instead of Oracle. The PostgreSQL default one-click installation is sufficient for the example. On Windows, I found it necessary to remove whitespace from the default installation path, and adding the </path/to/postgresql>/bin to the system Path variable has been helpful.<br /><br />For this example, we can create a new database called <em>examples</em>:<br /><div style="overflow:auto;width:60%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /> psql -U postgres -c "CREATE DATABASE examples" -d template1<br /></div><br /><br />We can also create a new database user and assign full privileges:<br /><div style="overflow:auto;width:60%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /> psql -U postgres -c "CREATE USER hibernate_query WITH PASSWORD 'hibernate_query'" -d examples<br /> psql -U postgres -c "grant all privileges on database examples to hibernate_query" -d examples<br /></div><br /><br /><h4>Create an M2Eclipse Project</h4><br />Creating a simple M2Eclipse project without an archetype should be familiar if you have followed <a href="http://timezra.blogspot.com/2009/03/spring-30-quartz-batch-with-maven2.html">previous posts in this series</a>. Note that, for our example, we will configure our <em>pom.xml</em> for Spring 3.0.0.M3 and for the postgresql 8.3-603.jdbc4 driver. Unlike in prior examples, no extra Maven2 setup of the Oracle JDBC driver is necessary since the PostgreSQL driver is distributed directly from the Maven2 repository.<br />Our <em>pom.xml</em> will look similar to this:<br /><div style="overflow:auto;width:100%;height:750px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0"</span> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span><br /> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span>4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>examples.hibernate.spring.query<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>examples.hibernate.spring.query<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span>examples.hibernate.spring.query<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>0.0.1-SNAPSHOT<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">description</span><span style="color: rgb(0,128,128);">></span>Hibernate Query Example<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">description</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>org.springframework.transaction<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.0.M3<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>org.springframework.orm<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.0.M3<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.hibernate<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>hibernate-annotations<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.4.0.GA<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.slf4j<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>slf4j-log4j12<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.5.2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>javassist<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>javassist<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.4.GA<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>cglib<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>cglib<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>commons-dbcp<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>commons-dbcp<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.2.2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>postgresql<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>postgresql<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>8.3-603.jdbc4<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>junit<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>junit<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>4.5<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>org.springframework.test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.0.M3<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repositories</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>SpringSource Enterprise Bundle Repository - External Bundle Milestones<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://repository.springsource.com/maven/bundles/milestone<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://repository.springsource.com/maven/bundles/release<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>SpringSource Enterprise Bundle Repository - External Bundle Releases<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://repository.springsource.com/maven/bundles/external<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repositories</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br />Similarly, our Spring <em>src/main/resources/applicationContext.xml</em> must also be configured for a PostgreSQL, rather than Oracle, connection:<br /><div style="overflow:auto;width:100%;height:750px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">beans</span> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/beans"</span><br /> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span> <span style="color: rgb(127,0,127);">xmlns:tx</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/tx"</span><br /> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/beans<br /> http://www.springframework.org/schema/beans/spring-beans.xsd<br /> http://www.springframework.org/schema/tx<br /> http://www.springframework.org/schema/tx/spring-tx.xsd"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"dataSource"</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.apache.commons.dbcp.BasicDataSource"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"driverClassName"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span>org.postgresql.Driver<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"username"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span>hibernate_query<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"password"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span>hibernate_query<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"url"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span>jdbc:postgresql://localhost:5432/examples<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"sessionFactory"</span><br /> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.orm.hibernate3.LocalSessionFactoryBean"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"dataSource"</span> <span style="color: rgb(127,0,127);">ref</span>=<span style="font-style: italic; color: rgb(42,0,255);">"dataSource"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"configLocation"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"classpath:/hibernate.cfg.xml"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"configurationClass"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.hibernate.cfg.AnnotationConfiguration"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernateProperties"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">props</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.show_sql"</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.format_sql"</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.generate_statistics"</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.use_sql_comments"</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.hbm2ddl.auto"</span><span style="color: rgb(0,128,128);">></span>create<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.dialect"</span><span style="color: rgb(0,128,128);">></span>org.hibernate.dialect.PostgreSQLDialect<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.query.factory_class"</span><span style="color: rgb(0,128,128);">></span>org.hibernate.hql.ast.ASTQueryTranslatorFactory<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">props</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"txManager"</span><br /> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.orm.hibernate3.HibernateTransactionManager"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"sessionFactory"</span> <span style="color: rgb(127,0,127);">ref</span>=<span style="font-style: italic; color: rgb(42,0,255);">"sessionFactory"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">tx:annotation-driven</span> <span style="color: rgb(127,0,127);">transaction-manager</span>=<span style="font-style: italic; color: rgb(42,0,255);">"txManager"</span> <span style="color: rgb(0,128,128);">/></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">beans</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><br />We can also create a very simple domain of authors. Every <em>Author</em> will have a first name, a last name and a generated id:<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">examples.hibernate.spring.query.domain;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Column;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Entity;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.GeneratedValue;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.GenerationType;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Id;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.SequenceGenerator;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Table;</span><br /><br /><span style="color: rgb(0,0,0);">@Entity</span><br /><span style="color: rgb(0,0,0);">@Table(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"AUTHOR"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">schema</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">""</span><span style="color: rgb(0,0,0);">)</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">Author</span> <span style="font-weight: bold; color: rgb(127,0,85);">implements</span> <span style="color: rgb(0,0,0);">java.io.Serializable</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">serialVersionUID</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">-6270202393794713117L;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">id;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">firstName;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">lastName;</span><br /><br /> <span style="color: rgb(0,0,0);">@Id</span><br /> <span style="color: rgb(0,0,0);">@GeneratedValue(strategy</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">GenerationType.SEQUENCE,</span> <span style="color: rgb(0,0,0);">generator</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"author_id_seq"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@SequenceGenerator(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"author_id_seq"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">sequenceName</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"author_id_seq"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"ID"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">getId()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setId(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">id)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.id</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"FIRST_NAME"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">50)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getFirstName()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">firstName;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setFirstName(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">firstName)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.firstName</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">firstName;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"LAST_NAME"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">50)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getLastName()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">lastName;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setLastName(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">lastName)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.lastName</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">lastName;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span></span><br /></div><br /><br />We can register our domain with Hibernate in the <em>src/main/resources/hibernate.cfg.xml</em>:<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><!</span><span style="color: rgb(63,127,127);">DOCTYPE</span> <span style="color: rgb(0,128,128);">hibernate-configuration</span> <span style="color: rgb(128,128,128);">PUBLIC</span><br /> <span style="color: rgb(0,128,128);">"-//Hibernate/Hibernate Configuration DTD 3.0//EN"</span><br /> <span style="color: rgb(63,127,95);">"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">hibernate-configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">session-factory</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">mapping</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"examples.hibernate.spring.query.domain.Author"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">session-factory</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">hibernate-configuration</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><br /><br /><h4>The Custom Query</h4><br />Suppose we want to run a custom query from Hibernate, but the resulting rows do not correspond directly to a Table or to the columns in a table. For example, suppose we want to find the number of unique first names for all authors.<br />Mapping the results of a custom query to the fields of a Hibernate POJO is very similar to mapping table columns.<br />For our example, we can call an individual result an <em>AuthorAggregate</em>. It will contain fields for a first name and a count of the number of occurrences for that first name. The aggregate must also have an id for uniquely identifying each result:<br /><div style="overflow:auto;width:100%;height:750px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">examples.hibernate.spring.query.domain;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Column;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Entity;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.GeneratedValue;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Id;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.annotations.GenericGenerator;</span><br /><br /><span style="color: rgb(0,0,0);">@Entity</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">AuthorAggregate</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">firstName;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Long</span> <span style="color: rgb(0,0,0);">nameCOunt;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setId(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">id)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.id</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Id</span><br /> <span style="color: rgb(0,0,0);">@GeneratedValue(generator</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"system-uuid"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@GenericGenerator(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"system-uuid"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">strategy</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"uuid"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">getId()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setFirstName(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">firstName)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.firstName</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">firstName;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"FIRST_NAME"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">50)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getFirstName()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">firstName;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setNameCount(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Long</span> <span style="color: rgb(0,0,0);">nameCOunt)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.nameCOunt</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">nameCOunt;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"NAME_COUNT"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Long</span> <span style="color: rgb(0,0,0);">getNameCount()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">nameCOunt;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span></span><br /></div><br /><br />We will register this object in our <em>src/main/resources/hibernate.cfg.xml</em> as part of our domain so that Hibernate can map the results of the query to the object's fields:<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;">....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">mapping</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"examples.hibernate.spring.query.domain.AuthorAggregate"</span> <span style="color: rgb(0,128,128);">/></span><br />....</span><br /></div><br /><br />We can test the execution of our query and the mapping of the results in JUnit with an <em>AuthorTest</em>:<br /><div style="overflow:auto;width:100%;height:750px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">examples.hibernate.spring.query.domain;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">org.junit.Assert.assertEquals;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Collection;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.SessionFactory;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.classic.Session;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.Before;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.Test;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.runner.RunWith;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.beans.factory.annotation.Autowired;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.ContextConfiguration;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.junit4.SpringJUnit4ClassRunner;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.transaction.TransactionConfiguration;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.transaction.annotation.Transactional;</span><br /><br /><span style="color: rgb(0,0,0);">@RunWith(SpringJUnit4ClassRunner.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">)</span><br /><span style="color: rgb(0,0,0);">@ContextConfiguration(locations</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(42,0,255);">"/applicationContext.xml"</span> <span style="color: rgb(0,0,0);">})</span><br /><span style="color: rgb(0,0,0);">@TransactionConfiguration(transactionManager</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"txManager"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">defaultRollback</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">)</span><br /><span style="color: rgb(0,0,0);">@Transactional</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">AuthorTest</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">AUTHORS_BY_FIRST_NAME</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(42,0,255);">"select first_name, count(author.id) as name_count, random() * 100000000000000000 as id "</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(42,0,255);">"from author "</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(42,0,255);">"group by author.first_name"</span><span style="color: rgb(0,0,0);">;</span><br /><br /> <span style="color: rgb(0,0,0);">@Autowired</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">SessionFactory</span> <span style="color: rgb(0,0,0);">sessionFactory;</span><br /><br /> <span style="color: rgb(0,0,0);">@Before</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setUp()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Session</span> <span style="color: rgb(0,0,0);">session</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession();</span><br /> <span style="color: rgb(0,0,0);">session.save(createCameronMcKenzie());</span><br /> <span style="color: rgb(0,0,0);">session.save(createChristianBauer());</span><br /> <span style="color: rgb(0,0,0);">session.save(createCameronJudd());</span><br /> <span style="color: rgb(0,0,0);">session.flush();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">findAggregationOfNames()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<AuthorAggregate></span> <span style="color: rgb(0,0,0);">authorsByName</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">findByFirstName();</span><br /> <span style="color: rgb(0,0,0);">assertEquals(2,</span> <span style="color: rgb(0,0,0);">authorsByName.size());</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">AuthorAggregate</span> <span style="color: rgb(0,0,0);">authorAggregate</span> <span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(0,0,0);">authorsByName)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(</span><span style="color: rgb(42,0,255);">"Cameron"</span><span style="color: rgb(0,0,0);">.equals(authorAggregate.getFirstName()))</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">assertEquals(Long.valueOf(2),</span> <span style="color: rgb(0,0,0);">authorAggregate.getNameCount());</span><br /> <span style="color: rgb(0,0,0);">}</span> <span style="font-weight: bold; color: rgb(127,0,85);">else</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">assertEquals(</span><span style="color: rgb(42,0,255);">"Christian"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">authorAggregate.getFirstName());</span><br /> <span style="color: rgb(0,0,0);">assertEquals(Long.valueOf(1),</span> <span style="color: rgb(0,0,0);">authorAggregate.getNameCount());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@SuppressWarnings(</span><span style="color: rgb(42,0,255);">"unchecked"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Collection<AuthorAggregate></span> <span style="color: rgb(0,0,0);">findByFirstName()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession()</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.createSQLQuery(AUTHORS_BY_FIRST_NAME)</span> <span style="color: rgb(63,127,95);">// <br /></span> <span style="color: rgb(0,0,0);">.addEntity(AuthorAggregate.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.list();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">createCameronMcKenzie()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">cameronMcKenzie</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Author();</span><br /> <span style="color: rgb(0,0,0);">cameronMcKenzie.setFirstName(</span><span style="color: rgb(42,0,255);">"Cameron"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">cameronMcKenzie.setLastName(</span><span style="color: rgb(42,0,255);">"McKenzie"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">cameronMcKenzie;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">createCameronJudd()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">cameronMcKenzie</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Author();</span><br /> <span style="color: rgb(0,0,0);">cameronMcKenzie.setFirstName(</span><span style="color: rgb(42,0,255);">"Cameron"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">cameronMcKenzie.setLastName(</span><span style="color: rgb(42,0,255);">"Judd"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">cameronMcKenzie;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">createChristianBauer()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">christianBauer</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Author();</span><br /> <span style="color: rgb(0,0,0);">christianBauer.setFirstName(</span><span style="color: rgb(42,0,255);">"Christian"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">christianBauer.setLastName(</span><span style="color: rgb(42,0,255);">"Bauer"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">christianBauer;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span></span><br /></div><br /><b>NB:</b> To generate a unique id for each result, we are using the PostgreSQL <em>random()</em> function. In Oracle, we could generate a string of random characters with a function call such as <em>dbms_random.string('P', 20)</em>. Also note that before we execute the native query, we must flush the Hibernate session to ensure that the Objects created and saved through HQL are persisted all the way to the database.<br /><br /><h4>The View</h4><br />Suppose that we want a list of all the last names of all the authors whose first name is <em>Cameron</em>.<br />Now that the author table exists in our database, we can create a custom view for this requirement through psql. We can connect to the <em>examples</em> database through psql<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /> psql -U hibernate_query -d examples<br /></div><br /><br />We will create the list of surnames directly through SQL:<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /><span style="font-weight: bold; color: rgb(127,0,85);">CREATE OR REPLACE VIEW</span> cameron <span style="font-weight: bold; color: rgb(127,0,85);">AS</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">SELECT</span> last_name <span style="font-weight: bold; color: rgb(127,0,85);">AS</span> surname<br /> <span style="font-weight: bold; color: rgb(127,0,85);">FROM</span> author<br /> <span style="font-weight: bold; color: rgb(127,0,85);">WHERE</span> first_name = <span style="color: rgb(42,0,255);">'Cameron'</span>;<br /></div><br /><br />Setting up the Hibernate domain object for this view is similar to mapping the results of a custom query to an annotated POJO as described above. For this example, instead of creating the native query inline and registering the output Entity directly with the query, we will utilize a javax.persistence annotation to register a NamedNativeQuery directly with our domain object, <em>Cameron</em>:<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">examples.hibernate.spring.query.domain;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Column;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Entity;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Id;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.NamedNativeQuery;</span><br /><br /><span style="color: rgb(0,0,0);">@Entity</span><br /><span style="color: rgb(0,0,0);">@NamedNativeQuery(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"findUniqueCameronsInOrder"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">query</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"select * from cameron order by surname"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">resultClass</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">Cameron.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">)</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">Cameron</span> <span style="font-weight: bold; color: rgb(127,0,85);">implements</span> <span style="color: rgb(0,0,0);">java.io.Serializable</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">serialVersionUID</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">8765016103450361311L;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">surname;</span><br /><br /> <span style="color: rgb(0,0,0);">@Id</span><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"SURNAME"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">50)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getSurname()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">surname;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setSurname(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">surname)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.surname</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">surname;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span></span><br /></div><br /><b>NB:</b> Our named query is doing slightly more than just selecting everything from the view. It selects only unique surnames, thus ensuring that the surname can be used as the <em>@Id</em>, and it also orders the returned surnames alphabetically.<br /><br />We will again register this domain object with Hibernate in the <em>src/main/resources/hibernate.cfg.xml</em>:<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;">....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">mapping</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"examples.hibernate.spring.query.domain.Cameron"</span> <span style="color: rgb(0,128,128);">/></span><br />....<br /></span><br /></div><br /><br />We can run the query with a few additions to the JUnit test:<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /><span style="color: rgb(0,0,0);">....</span><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">findTheCameronsInTheView()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">List<Cameron></span> <span style="color: rgb(0,0,0);">camerons</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">findUniqueCameronsInOrder();</span><br /> <span style="color: rgb(0,0,0);">assertEquals(2,</span> <span style="color: rgb(0,0,0);">camerons.size());</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Cameron</span> <span style="color: rgb(0,0,0);">judd</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">camerons.get(0);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Cameron</span> <span style="color: rgb(0,0,0);">mcKenzie</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">camerons.get(1);</span><br /> <span style="color: rgb(0,0,0);">assertEquals(</span><span style="color: rgb(42,0,255);">"Judd"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">judd.getSurname());</span><br /> <span style="color: rgb(0,0,0);">assertEquals(</span><span style="color: rgb(42,0,255);">"McKenzie"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">mcKenzie.getSurname());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@SuppressWarnings(</span><span style="color: rgb(42,0,255);">"unchecked"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">List<Cameron></span> <span style="color: rgb(0,0,0);">findUniqueCameronsInOrder()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession()</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.getNamedQuery(</span><span style="color: rgb(42,0,255);">"findUniqueCameronsInOrder"</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.list();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">....</span><br /></span><br /></div><br /><br /><h4>Conclusion</h4><br />In this 12K project, we now have two examples for registering Hibernate-annotated POJOs with database structures that do not correspond directly to tables.<br /><img src="http://farm3.static.flickr.com/2177/3529378675_aefaca0c12_o.png" alt="The query example project structure.">Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com63tag:blogger.com,1999:blog-106449775438946661.post-34306756627359022212009-04-04T00:32:00.000-07:002009-05-28T17:01:11.122-07:00Data Modelling With Hibernate<h4>Goal:</h4><br />This article is an exploration of composition and inheritance relationships with Hibernate and Spring. The article begins with boilerplate project setup using Maven2 and presents individual examples of one-to-one, one-to-many and many-to-many relationships, as well as one way to map inheritance to a database schema. JUnit tests emphasize the interesting features of these relationships. By the end of the tutorial, we will have a framework and the tools for building more complex domains from these simple models.<br /><br /><h4>Project Setup</h4><br />Our initial project setup is essentially identical to that of the <a href="http://timezra.blogspot.com/2009/03/custom-inserts-with-hibernate.html">previous post</a> in the series, where we use the M2 plug-in for Eclipse to create a simple Maven2 project. For this example, we specify our dependencies (Spring, Hibernate, JUnit), create a Spring application context for Hibernate session management, create a Hibernate mapping file to register our annotated domain and create a pristine database schema (in Oracle).<br /><br />The <em>pom.xml</em> contains our Hibernate 3.4, Spring 3.0, JUnit 4.4 and Oracle driver dependencies.<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0"</span> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span><br /> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span>4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>timezra.blog.hibernate.data_modelling<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>timezra.blog.hibernate.data_modelling<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span>timezra.blog.hibernate.data_modelling<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>0.0.1-SNAPSHOT<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">description</span><span style="color: rgb(0,128,128);">></span>Hibernate Data Modelling Example<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">description</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>org.springframework.transaction<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.0.M2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>org.springframework.orm<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.0.M2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.hibernate<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>hibernate-annotations<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.4.0.GA<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.slf4j<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>slf4j-log4j12<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.5.2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>javassist<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>javassist<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.4.GA<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>cglib<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>cglib<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>commons-dbcp<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>commons-dbcp<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.2.2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>com.oracle<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>ojdbc14<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>10.2.0.2.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>junit<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>junit<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>4.5<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>org.springframework.test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.0.M2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repositories</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>SpringSource Enterprise Bundle Repository - External Bundle Milestones<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://repository.springsource.com/maven/bundles/milestone<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://repository.springsource.com/maven/bundles/release<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>SpringSource Enterprise Bundle Repository - External Bundle Releases<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://repository.springsource.com/maven/bundles/external<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repositories</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><br />The <em>src/main/resources/applicationContext.xml</em> conatins our Hibernate connection and session configuration and our transaction manager.<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">beans</span> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/beans"</span><br /> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span> <span style="color: rgb(127,0,127);">xmlns:tx</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/tx"</span><br /> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/beans<br /> http://www.springframework.org/schema/beans/spring-beans.xsd<br /> http://www.springframework.org/schema/tx<br /> http://www.springframework.org/schema/tx/spring-tx.xsd"</span><span style="color: rgb(0,128,128);">></span><br /> <br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"dataSource"</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.apache.commons.dbcp.BasicDataSource"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"driverClassName"</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span>oracle.jdbc.driver.OracleDriver<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"username"</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span>data_modelling<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"password"</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span>data_modelling<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"url"</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span>jdbc:oracle:thin:@localhost:1521:orcl<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"sessionFactory"</span><br /> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.orm.hibernate3.LocalSessionFactoryBean"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"dataSource"</span> <span style="color: rgb(127,0,127);">ref</span>=<span style="font-style: italic; color: rgb(42,0,255);">"dataSource"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"configLocation"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"classpath:/hibernate.cfg.xml"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"configurationClass"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.hibernate.cfg.AnnotationConfiguration"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernateProperties"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">props</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.show_sql"</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.format_sql"</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.generate_statistics"</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.use_sql_comments"</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.hbm2ddl.auto"</span><span style="color: rgb(0,128,128);">></span>create<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.dialect"</span><span style="color: rgb(0,128,128);">></span>org.hibernate.dialect.Oracle10gDialect<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.query.factory_class"</span><span style="color: rgb(0,128,128);">></span>org.hibernate.hql.classic.ClassicQueryTranslatorFactory<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">props</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"txManager"</span><br /> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.orm.hibernate3.HibernateTransactionManager"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"sessionFactory"</span> <span style="color: rgb(127,0,127);">ref</span>=<span style="font-style: italic; color: rgb(42,0,255);">"sessionFactory"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">tx:annotation-driven</span> <span style="color: rgb(127,0,127);">transaction-manager</span>=<span style="font-style: italic; color: rgb(42,0,255);">"txManager"</span><span style="color: rgb(0,128,128);">/></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">beans</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br />The <em>src/main/resources/hibernate.cfg.xml</em> is our registry for annotated Hibernate domain Objects.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><!</span><span style="color: rgb(63,127,127);">DOCTYPE</span> <span style="color: rgb(0,128,128);">hibernate-configuration</span> <span style="color: rgb(128,128,128);">PUBLIC</span><br /> <span style="color: rgb(0,128,128);">"-//Hibernate/Hibernate Configuration DTD 3.0//EN"</span><br /> <span style="color: rgb(63,127,95);">"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">hibernate-configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">session-factory</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">session-factory</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">hibernate-configuration</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br />We can create a pristine database schema from sqlplus.<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /> sqlplus connect as SYSDBA<br /> create user data_modelling identified by data_modelling default tablespace users temporary tablespace temp;<br /> grant connect, resource to data_modelling;<br /> grant create table to data_modelling;<br /></span><br /></div><br /><br />With that infrastructural boilerplate out of the way, we can begin defining our domain. For this example, our domain consists of libraries, books and authors.<br />A library can contain any number of books, and books can be present in any number of libraries. A book is written by an author. An author can write any number of books.<br /><br /><h4>One to One</h4><br />Suppose that a Library has an Address, and the Address must be unique per Library. That is, there cannot be more than one Library for a given Address. We can say that the Library and the Address have a one-to-one relationship.<br />One way to representing such a relationship with tables in a relational database would be for these two entities to share a primary key. That is, the primary key of one table can have a foreign-key reference to another table.<br /><img src="http://farm4.static.flickr.com/3360/3410576471_89039c3c97_o.png" alt="A one-to-one relationship between a Library and an Address." /><br /><br />We first need to declare that our domain will contain a Library and an Address in the <em>src/main/resources/hibernate.cfg.xml</em>.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;">....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">session-factory</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">mapping</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"timezra.blog.hibernate.data_modelling.domain.Library"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">mapping</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"timezra.blog.hibernate.data_modelling.domain.Address"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">session-factory</span><span style="color: rgb(0,128,128);">></span><br />....<br /></span><br /></div><br /><br />Suppose we decide that the Library's primary key depends on the primary key of the Address. Our Address object can have a sequence-generated primary key, and the corresponding id of the Library can have a foreign-key dependency on the Address id. You might be asking yourself what would happen if the relationship were reversed, if it would make any functional difference or if the difference is only semantic.<br /><em>Address.java</em><br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.data_modelling.domain;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Column;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Entity;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.GeneratedValue;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.GenerationType;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Id;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.SequenceGenerator;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Table;</span><br /><br /><span style="color: rgb(0,0,0);">@Entity</span><br /><span style="color: rgb(0,0,0);">@Table(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"ADDRESS"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">schema</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"DATA_MODELLING"</span><span style="color: rgb(0,0,0);">)</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">Address</span> <span style="font-weight: bold; color: rgb(127,0,85);">implements</span> <span style="color: rgb(0,0,0);">java.io.Serializable</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">serialVersionUID</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">1384654594047265994L;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">street1;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">street2;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">city;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">state;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">zipCode;</span><br /><br /> <span style="color: rgb(0,0,0);">@Id</span><br /> <span style="color: rgb(0,0,0);">@GeneratedValue(strategy</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">GenerationType.SEQUENCE,</span> <span style="color: rgb(0,0,0);">generator</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"address_id_seq"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@SequenceGenerator(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"address_id_seq"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">sequenceName</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"address_id_seq"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"ID"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">getId()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setId(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">id)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.id</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"STREET_1"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">50)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getStreet1()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">street1;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setStreet1(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">street1)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.street1</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">street1;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"STREET_2"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">50)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getStreet2()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">street2;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setStreet2(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">street2)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.street2</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">street2;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"CITY"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">50)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getCity()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">city;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setCity(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">city)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.city</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">city;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"STATE"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">2)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getState()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">state;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setState(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">state)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.state</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">state;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"ZIP_CODE"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">getZipCode()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">zipCode;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setZipCode(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">zipCode)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.zipCode</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">zipCode;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br />The primary key for <em>Library.java</em> is also specified as a generated value, but it uses a foreign-key generator instead of a sequence. We also need to specify that the primary key is a join column with the Address. This foreign-key id generator and the declaration that the Address can be joined to the Library by their primary keys is the essence of this relationship mapping. You now might be asking yourself what would happen if this relationship were reversed and if it would make sense for an Address to have a dependency on a Library.<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.data_modelling.domain;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.CascadeType;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Column;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Entity;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.GeneratedValue;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Id;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.OneToOne;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.PrimaryKeyJoinColumn;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Table;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.annotations.GenericGenerator;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.annotations.Parameter;</span><br /><br /><span style="color: rgb(0,0,0);">@Entity</span><br /><span style="color: rgb(0,0,0);">@Table(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"LIBRARY"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">schema</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"DATA_MODELLING"</span><span style="color: rgb(0,0,0);">)</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">Library</span> <span style="font-weight: bold; color: rgb(127,0,85);">implements</span> <span style="color: rgb(0,0,0);">java.io.Serializable</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">serialVersionUID</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">556729119500294739L;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">name;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Address</span> <span style="color: rgb(0,0,0);">address;</span><br /><br /> <span style="color: rgb(0,0,0);">@Id</span><br /> <span style="color: rgb(0,0,0);">@GeneratedValue(generator</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"foreign"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@GenericGenerator(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"foreign"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">strategy</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"foreign"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">parameters</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(0,0,0);">@Parameter(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"property"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">value</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"address"</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">})</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">getId()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setId(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">id)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.id</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"NAME"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">50)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getName()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">name;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setName(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">name)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">name;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@OneToOne(cascade</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">CascadeType.ALL,</span> <span style="color: rgb(0,0,0);">optional</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@PrimaryKeyJoinColumn</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Address</span> <span style="color: rgb(0,0,0);">getAddress()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">address;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setAddress(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Address</span> <span style="color: rgb(0,0,0);">address)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.address</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">address;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br />We can verify that exactly one unique Address can be associated with a Library with a test case.<br /><em>LibraryTest.java</em><br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.data_modelling.domain;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">org.junit.Assert.fail;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.NonUniqueObjectException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.SessionFactory;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.Test;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.runner.RunWith;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.beans.factory.annotation.Autowired;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.ContextConfiguration;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.junit4.SpringJUnit4ClassRunner;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.transaction.TransactionConfiguration;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.transaction.annotation.Transactional;</span><br /><br /><span style="color: rgb(0,0,0);">@RunWith(SpringJUnit4ClassRunner.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">)</span><br /><span style="color: rgb(0,0,0);">@ContextConfiguration(locations</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(42,0,255);">"/applicationContext.xml"</span> <span style="color: rgb(0,0,0);">})</span><br /><span style="color: rgb(0,0,0);">@TransactionConfiguration(transactionManager</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"txManager"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">defaultRollback</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">)</span><br /><span style="color: rgb(0,0,0);">@Transactional</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">LibraryTest</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="color: rgb(0,0,0);">@Autowired</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">SessionFactory</span> <span style="color: rgb(0,0,0);">sessionFactory;</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">onlyOneLibraryCanHaveaGivenAddress()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Address</span> <span style="color: rgb(0,0,0);">address</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">createAddress();</span><br /> <span style="color: rgb(0,0,0);">createSeattleMainBranch(address);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">try</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">createSeattleSatelliteBranch(address);</span><br /> <span style="color: rgb(0,0,0);">fail(</span><span style="color: rgb(42,0,255);">"A given address cannot be associated with more than one library."</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">}</span> <span style="font-weight: bold; color: rgb(127,0,85);">catch</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">NonUniqueObjectException</span> <span style="color: rgb(0,0,0);">e)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(63,127,95);">// pass<br /></span> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">createSeattleSatelliteBranch(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Address</span> <span style="color: rgb(0,0,0);">address)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Library</span> <span style="color: rgb(0,0,0);">seattleSatelliteBranch</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Library();</span><br /> <span style="color: rgb(0,0,0);">seattleSatelliteBranch.setName(</span><span style="color: rgb(42,0,255);">"Ballard Branch"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">seattleSatelliteBranch.setAddress(address);</span><br /> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession().save(seattleSatelliteBranch);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">createSeattleMainBranch(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Address</span> <span style="color: rgb(0,0,0);">address)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Library</span> <span style="color: rgb(0,0,0);">seattleMainBranch</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Library();</span><br /> <span style="color: rgb(0,0,0);">seattleMainBranch.setName(</span><span style="color: rgb(42,0,255);">"Seattle Central Library"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">seattleMainBranch.setAddress(address);</span><br /> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession().save(seattleMainBranch);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Address</span> <span style="color: rgb(0,0,0);">createAddress()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Address</span> <span style="color: rgb(0,0,0);">address</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Address();</span><br /> <span style="color: rgb(0,0,0);">address.setStreet1(</span><span style="color: rgb(42,0,255);">"1000 Fourth Ave."</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">address.setCity(</span><span style="color: rgb(42,0,255);">"Seattle"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">address.setState(</span><span style="color: rgb(42,0,255);">"WA"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">address.setZipCode(98104);</span><br /> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession().save(address);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">address;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br /><h4>One to Many</h4><br />As previously noted, each Book has a single Author, and an Author can write any number of Books. Such a requirement (while simplistic because in actuality a Book could have multiple Authors) can be mapped to a one-to-many relationship for the purpose of this tutorial.<br />In our database, this type of compositional relationship can best be represented by a foreign-key dependency from the <em>many</em> side to the <em>one</em> side. Whereas, in our domain Object, an inuitive way to demonstrate this relationship would be for each Author to reference the books she has written and for each Book to have a reference to its Author, the tabular relationship would be indicated as a field only in the composed entity (Book).<br /><img src="http://farm4.static.flickr.com/3337/3410576469_ec87bd8604_o.png" alt="A one-to-many relationship between an Author and Books." /><br /><br />Again, we will declare that Books and Authors are part of our domain in <em>src/main/resources/hibernate.cfg.xml</em>.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;">....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">session-factory</span><span style="color: rgb(0,128,128);">></span><br /> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">mapping</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"timezra.blog.hibernate.data_modelling.domain.Author"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">mapping</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"timezra.blog.hibernate.data_modelling.domain.Book"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">session-factory</span><span style="color: rgb(0,128,128);">></span><br />....</span><br /></div><br /><br />An <em>Author.java</em> writes Books, and to indicate this relationship, we can use the <em>@OneToMany</em> declaration.<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.data_modelling.domain;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.HashSet;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Set;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.CascadeType;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Column;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Entity;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.FetchType;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.GeneratedValue;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.GenerationType;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Id;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.OneToMany;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.SequenceGenerator;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Table;</span><br /><br /><span style="color: rgb(0,0,0);">@Entity</span><br /><span style="color: rgb(0,0,0);">@Table(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"AUTHOR"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">schema</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"DATA_MODELLING"</span><span style="color: rgb(0,0,0);">)</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">Author</span> <span style="font-weight: bold; color: rgb(127,0,85);">implements</span> <span style="color: rgb(0,0,0);">java.io.Serializable</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">serialVersionUID</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">3091725775359171905L;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">firstName;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">lastName;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Set<Book></span> <span style="color: rgb(0,0,0);">books</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">HashSet<Book>();</span><br /><br /> <span style="color: rgb(0,0,0);">@Id</span><br /> <span style="color: rgb(0,0,0);">@GeneratedValue(strategy</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">GenerationType.SEQUENCE,</span> <span style="color: rgb(0,0,0);">generator</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"author_id_seq"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@SequenceGenerator(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"author_id_seq"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">sequenceName</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"author_id_seq"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"ID"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">getId()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setId(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">id)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.id</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"FIRST_NAME"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">50)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getFirstName()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">firstName;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setFirstName(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">firstName)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.firstName</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">firstName;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"LAST_NAME"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">50)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getLastName()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">lastName;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setLastName(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">lastName)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.lastName</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">lastName;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@OneToMany(cascade</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">CascadeType.ALL,</span> <span style="color: rgb(0,0,0);">fetch</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">FetchType.LAZY,</span> <span style="color: rgb(0,0,0);">mappedBy</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"author"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Set<Book></span> <span style="color: rgb(0,0,0);">getBooks()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">books;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setBooks(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Set<Book></span> <span style="color: rgb(0,0,0);">books)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.books</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">books;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br />Similarly, a <em>Book.java</em> has an Author, so we can declare this relationship as <em>@ManyToOne</em>. We will also specify how the database resolves this reference, so we declare our <em>@JoinColumn</em> here, similar to how the foreign-key reference is in the Book table in the database.<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.data_modelling.domain;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Date;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Column;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Entity;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.FetchType;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.GeneratedValue;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.GenerationType;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Id;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.JoinColumn;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.ManyToOne;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.SequenceGenerator;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Table;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Temporal;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.TemporalType;</span><br /><br /><span style="color: rgb(0,0,0);">@Entity</span><br /><span style="color: rgb(0,0,0);">@Table(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"BOOK"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">schema</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"DATA_MODELLING"</span><span style="color: rgb(0,0,0);">)</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">Book</span> <span style="font-weight: bold; color: rgb(127,0,85);">implements</span> <span style="color: rgb(0,0,0);">java.io.Serializable</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">serialVersionUID</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">4347977827397320578L;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">title;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">pages;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">author;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">publisher;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Date</span> <span style="color: rgb(0,0,0);">publicationDate;</span><br /><br /> <span style="color: rgb(0,0,0);">@Id</span><br /> <span style="color: rgb(0,0,0);">@GeneratedValue(strategy</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">GenerationType.SEQUENCE,</span> <span style="color: rgb(0,0,0);">generator</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"book_id_seq"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@SequenceGenerator(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"book_id_seq"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">sequenceName</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"book_id_seq"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"ID"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">getId()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setId(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">id)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.id</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"PUBLISHER"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">50)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getPublisher()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">publisher;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setPublisher(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">publisher)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.publisher</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">publisher;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Temporal(TemporalType.TIMESTAMP)</span><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"PUBLICATION_DATE"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">11)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Date</span> <span style="color: rgb(0,0,0);">getPublicationDate()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">publicationDate;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setPublicationDate(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Date</span> <span style="color: rgb(0,0,0);">publicationDate)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.publicationDate</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">publicationDate;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"TITLE"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">200)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getTitle()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">title;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setTitle(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">title)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.title</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">title;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"PAGES"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">getPages()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">pages;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setPages(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">pages)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.pages</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">pages;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@ManyToOne(fetch</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">FetchType.LAZY)</span><br /> <span style="color: rgb(0,0,0);">@JoinColumn(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"AUTHOR_ID"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">getAuthor()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">author;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setAuthor(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">author)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.author</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">author;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br />We do not explicitly reference the foreign-key dependency in the Book table except in the meta-data. In a test case, we can execute a SQL query to get the value from this foreign-key column and compare it to the id that it references in the Author table. <br /><em>BookTest.java</em><br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.data_modelling.domain;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">org.junit.Assert.assertEquals;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.math.BigDecimal;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.text.ParseException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.text.SimpleDateFormat;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.SessionFactory;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.classic.Session;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.Test;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.runner.RunWith;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.beans.factory.annotation.Autowired;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.ContextConfiguration;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.junit4.SpringJUnit4ClassRunner;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.transaction.TransactionConfiguration;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.transaction.annotation.Transactional;</span><br /><br /><span style="color: rgb(0,0,0);">@RunWith(SpringJUnit4ClassRunner.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">)</span><br /><span style="color: rgb(0,0,0);">@ContextConfiguration(locations</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(42,0,255);">"/applicationContext.xml"</span> <span style="color: rgb(0,0,0);">})</span><br /><span style="color: rgb(0,0,0);">@TransactionConfiguration(transactionManager</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"txManager"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">defaultRollback</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">)</span><br /><span style="color: rgb(0,0,0);">@Transactional</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">BookTest</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="color: rgb(0,0,0);">@Autowired</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">SessionFactory</span> <span style="color: rgb(0,0,0);">sessionFactory;</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">aBookHasAForeignKeyReferenceToAnAuthor()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">cameronMcKenzie</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">createCameronMcKenzie();</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">hibernateMadeEasy</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">createHibernateMadeEasy(cameronMcKenzie);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Session</span> <span style="color: rgb(0,0,0);">session</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession();</span><br /> <span style="color: rgb(0,0,0);">session.flush();</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">BigDecimal</span> <span style="color: rgb(0,0,0);">authorId</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">(BigDecimal)</span> <span style="color: rgb(0,0,0);">session</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.createSQLQuery(</span><span style="color: rgb(42,0,255);">"SELECT author_id FROM book WHERE id = :vId"</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.setParameter(</span><span style="color: rgb(42,0,255);">"vId"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">hibernateMadeEasy.getId())</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.uniqueResult();</span><br /> <span style="color: rgb(0,0,0);">assertEquals(cameronMcKenzie.getId(),</span> <span style="color: rgb(0,0,0);">authorId.intValue());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">createHibernateMadeEasy(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">cameronMcKenzie)</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">ParseException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">hibernateMadeEasy</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Book();</span><br /> <span style="color: rgb(0,0,0);">hibernateMadeEasy.setTitle(</span><span style="color: rgb(42,0,255);">"Hibernate Made Easy"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">hibernateMadeEasy.setAuthor(cameronMcKenzie);</span><br /> <span style="color: rgb(0,0,0);">hibernateMadeEasy.setPublisher(</span><span style="color: rgb(42,0,255);">"PulpJava"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">hibernateMadeEasy.setPublicationDate(</span><span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">SimpleDateFormat(</span><span style="color: rgb(42,0,255);">"MM-yyyy"</span><span style="color: rgb(0,0,0);">).parse(</span><span style="color: rgb(42,0,255);">"04-2008"</span><span style="color: rgb(0,0,0);">));</span><br /> <span style="color: rgb(0,0,0);">hibernateMadeEasy.setPages(444);</span><br /> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession().save(hibernateMadeEasy);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">hibernateMadeEasy;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">createCameronMcKenzie()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">cameronMcKenzie</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Author();</span><br /> <span style="color: rgb(0,0,0);">cameronMcKenzie.setFirstName(</span><span style="color: rgb(42,0,255);">"Cameron"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">cameronMcKenzie.setLastName(</span><span style="color: rgb(42,0,255);">"McKenzie"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession().save(cameronMcKenzie);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">cameronMcKenzie;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br /><h4>Many to Many</h4><br />A Library has many Books and a Book can be found in any number of Libraries. In a database, this type of complex relationship cannot be captured by using foreign-key references from Books to Libraries or vice versa. Most problems in computer science can be solved by adding a layer of indirection, and this is no exception. Many-to-many relationships can be represented in a relational database with a cross-reference table.<br /><img src="http://farm4.static.flickr.com/3570/3410576465_c33b88604f_o.png" alt="A many-to-many relationship between an Books and Libraries." /><br /><br />Fortunately, Hibernate will automatically create such a cross-reference table, so we do not need to register any other Objects with our domain. We can simply annotate our existing domain Objects to indicate that Libraries and Books have a <em>@ManyToMany</em> relationship and that the database can use a <em>@JoinTable</em> to represent this relationship.<br /><em>Library.java</em><br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /> <span style="color: rgb(0,0,0);">....</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Set<Book></span> <span style="color: rgb(0,0,0);">books</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">HashSet<Book>();</span><br /> <span style="color: rgb(0,0,0);">....</span><br /> <span style="color: rgb(0,0,0);">@ManyToMany(targetEntity</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">Book.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@JoinTable(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"BOOK_LIBRARY"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">joinColumns</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">@JoinColumn(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"LIBRARY_ID"</span><span style="color: rgb(0,0,0);">),</span> <span style="color: rgb(0,0,0);">inverseJoinColumns</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">@JoinColumn(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"BOOK_ID"</span><span style="color: rgb(0,0,0);">))</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Set<Book></span> <span style="color: rgb(0,0,0);">getBooks()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">books;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setBooks(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Set<Book></span> <span style="color: rgb(0,0,0);">books)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.books</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">books;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">....</span></span><br /></div><br /><br /><em>Book.java</em><br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /> <span style="color: rgb(0,0,0);">....</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Set<Library></span> <span style="color: rgb(0,0,0);">libraries</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">HashSet<Library>();</span><br /> <span style="color: rgb(0,0,0);">....</span><br /> <span style="color: rgb(0,0,0);">@ManyToMany(mappedBy</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"books"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">targetEntity</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">Library.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Set<Library></span> <span style="color: rgb(0,0,0);">getLibraries()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">libraries;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setLibraries(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Set<Library></span> <span style="color: rgb(0,0,0);">libraries)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.libraries</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">libraries;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">....</span></span><br /></div><br /><br />With a <em>LibraryBookTest.java</em>, we can demonstrate the difference between how joins are performed between HQL and SQL.<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.data_modelling.domain;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">org.junit.Assert.assertFalse;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">org.junit.Assert.assertTrue;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.text.ParseException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.text.SimpleDateFormat;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Arrays;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Collection;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Date;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.List;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.SessionFactory;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.Before;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.Test;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.runner.RunWith;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.beans.factory.annotation.Autowired;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.ContextConfiguration;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.junit4.SpringJUnit4ClassRunner;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.transaction.TransactionConfiguration;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.transaction.annotation.Transactional;</span><br /><br /><span style="color: rgb(0,0,0);">@RunWith(SpringJUnit4ClassRunner.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">)</span><br /><span style="color: rgb(0,0,0);">@ContextConfiguration(locations</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(42,0,255);">"/applicationContext.xml"</span> <span style="color: rgb(0,0,0);">})</span><br /><span style="color: rgb(0,0,0);">@TransactionConfiguration(transactionManager</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"txManager"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">defaultRollback</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">)</span><br /><span style="color: rgb(0,0,0);">@Transactional</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">LibraryBookTest</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="color: rgb(0,0,0);">@Autowired</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">SessionFactory</span> <span style="color: rgb(0,0,0);">sessionFactory;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">hibernateMadeEasy;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">javaPersistenceWithHibernate;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">springInAction;</span><br /><br /> <span style="color: rgb(0,0,0);">@Before</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setUp()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">createSeattleMainBranch(</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">createAddress(),</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">hibernateMadeEasy</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">createHibernateMadeEasy(),</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">javaPersistenceWithHibernate</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">createJavaPersistenceWithHibernate());</span><br /> <span style="color: rgb(0,0,0);">springInAction</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">createSpringInAction();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">findAllTheBooksInTheSeattleMainLibraryWithHQL()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<?></span> <span style="color: rgb(0,0,0);">books</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession()</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.createQuery(</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(42,0,255);">"select b "</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(42,0,255);">"from Library l, Book b "</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(42,0,255);">"where b in elements(l.books) "</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(42,0,255);">" and l.name = 'Seattle Central Library'"</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.list();</span><br /> <span style="color: rgb(0,0,0);">assertTrue(books.contains(hibernateMadeEasy));</span><br /> <span style="color: rgb(0,0,0);">assertTrue(books.contains(javaPersistenceWithHibernate));</span><br /> <span style="color: rgb(0,0,0);">assertFalse(books.contains(springInAction));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">findAllTheBooksInTheSeattleMainLibraryWithSQL()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">List<?></span> <span style="color: rgb(0,0,0);">books</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession()</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.createSQLQuery(</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(42,0,255);">"SELECT b.* "</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(42,0,255);">"FROM book b, book_library bl, library l "</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(42,0,255);">"WHERE b.id = bl.book_id "</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(42,0,255);">" AND bl.library_id = l.id "</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(42,0,255);">" AND l.name = 'Seattle Central Library'"</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.addEntity(Book.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(63,127,95);">// <br /></span> <span style="color: rgb(0,0,0);">.list();</span><br /> <span style="color: rgb(0,0,0);">assertTrue(books.contains(hibernateMadeEasy));</span><br /> <span style="color: rgb(0,0,0);">assertTrue(books.contains(javaPersistenceWithHibernate));</span><br /> <span style="color: rgb(0,0,0);">assertFalse(books.contains(springInAction));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">createHibernateMadeEasy()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">ParseException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">createBook(createAuthor(</span><span style="color: rgb(42,0,255);">"Cameron"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">"McKenzie"</span><span style="color: rgb(0,0,0);">),</span> <span style="color: rgb(42,0,255);">"Hibernate Made Easy"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">"PulpJava"</span><span style="color: rgb(0,0,0);">,</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">SimpleDateFormat(</span><br /> <span style="color: rgb(42,0,255);">"MM-yyyy"</span><span style="color: rgb(0,0,0);">).parse(</span><span style="color: rgb(42,0,255);">"04-2008"</span><span style="color: rgb(0,0,0);">),</span> <span style="color: rgb(0,0,0);">444);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">createJavaPersistenceWithHibernate()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">ParseException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">createBook(createAuthor(</span><span style="color: rgb(42,0,255);">"Christian"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">"Bauer"</span><span style="color: rgb(0,0,0);">),</span> <span style="color: rgb(42,0,255);">"Java Persistence with Hibernate"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">"Manning Publications"</span><span style="color: rgb(0,0,0);">,</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">SimpleDateFormat(</span><span style="color: rgb(42,0,255);">"MM-yyyy"</span><span style="color: rgb(0,0,0);">).parse(</span><span style="color: rgb(42,0,255);">"11-2006"</span><span style="color: rgb(0,0,0);">),</span> <span style="color: rgb(0,0,0);">904);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">createSpringInAction()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">ParseException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">createBook(createAuthor(</span><span style="color: rgb(42,0,255);">"Craig"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">"Walls"</span><span style="color: rgb(0,0,0);">),</span> <span style="color: rgb(42,0,255);">"Spring in Action"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">"Manning Publications"</span><span style="color: rgb(0,0,0);">,</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">SimpleDateFormat(</span><br /> <span style="color: rgb(42,0,255);">"MM-yyyy"</span><span style="color: rgb(0,0,0);">).parse(</span><span style="color: rgb(42,0,255);">"08-2007"</span><span style="color: rgb(0,0,0);">),</span> <span style="color: rgb(0,0,0);">650);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">createAuthor(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">firstName,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">lastName)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">author</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Author();</span><br /> <span style="color: rgb(0,0,0);">author.setFirstName(firstName);</span><br /> <span style="color: rgb(0,0,0);">author.setLastName(lastName);</span><br /> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession().save(author);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">author;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">createBook(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">author,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">title,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">publisher,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Date</span> <span style="color: rgb(0,0,0);">publicationDate,</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">pages)</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">ParseException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Book</span> <span style="color: rgb(0,0,0);">hibernateMadeEasy</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Book();</span><br /> <span style="color: rgb(0,0,0);">hibernateMadeEasy.setTitle(title);</span><br /> <span style="color: rgb(0,0,0);">hibernateMadeEasy.setAuthor(author);</span><br /> <span style="color: rgb(0,0,0);">hibernateMadeEasy.setPublisher(publisher);</span><br /> <span style="color: rgb(0,0,0);">hibernateMadeEasy.setPublicationDate(publicationDate);</span><br /> <span style="color: rgb(0,0,0);">hibernateMadeEasy.setPages(pages);</span><br /> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession().save(hibernateMadeEasy);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">hibernateMadeEasy;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">createSeattleMainBranch(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Address</span> <span style="color: rgb(0,0,0);">address,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Book...</span> <span style="color: rgb(0,0,0);">books)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Library</span> <span style="color: rgb(0,0,0);">seattleMainBranch</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Library();</span><br /> <span style="color: rgb(0,0,0);">seattleMainBranch.setName(</span><span style="color: rgb(42,0,255);">"Seattle Central Library"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">seattleMainBranch.setAddress(address);</span><br /> <span style="color: rgb(0,0,0);">seattleMainBranch.getBooks().addAll(Arrays.asList(books));</span><br /> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession().save(seattleMainBranch);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Address</span> <span style="color: rgb(0,0,0);">createAddress()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Address</span> <span style="color: rgb(0,0,0);">address</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Address();</span><br /> <span style="color: rgb(0,0,0);">address.setStreet1(</span><span style="color: rgb(42,0,255);">"1000 Fourth Ave."</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">address.setCity(</span><span style="color: rgb(42,0,255);">"Seattle"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">address.setState(</span><span style="color: rgb(42,0,255);">"WA"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">address.setZipCode(98104);</span><br /> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession().save(address);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">address;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br /><h4>Inheritance</h4><br />While relational databases represent flat data structures very well, Object inheritance relationships do not naturally map. Suppose we want our domain to contain regular People as well as Authors. An Author is a Person who has written any number of Books. A Person is not necessarily an Author, however. <br />One way to represent this relationship in a database is to use a single table to represent all types of People and to use a discriminator to differentiate among the various types of people. Such a table would contain all the attributes for all the types of people in the domain, even if the given attributes do not apply to a particular type of person. For our example because we have such a small number of types of People in our system, the <em>SingleTableInheritance</em> model will suffice. For domains that contain deep or broad inheritance trees, this mapping may not be the best and other mappings should be explored.<br /><img src="http://farm4.static.flickr.com/3377/3410576459_754d83415b_o.png" alt="A single-table inheritance relationship between Person and Author." /><br /><br />People are now part of the domain, and we can update our <em>src/main/resources/hibernate.cfg.xml</em> registry.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;">....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">mapping</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"timezra.blog.hibernate.data_modelling.domain.Person"</span> <span style="color: rgb(0,128,128);">/></span><br />....</span><br /></div><br /><br />Here, all types of <em>Person.java</em> will be present in the same database table because of the configured <em>@Inheritance</em> strategy. Different People can be distinguished with a <em>@DiscriminatorType</em> in a <em>@DiscriminatorColumn</em>.<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.data_modelling.domain;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Column;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.DiscriminatorColumn;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.DiscriminatorType;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.DiscriminatorValue;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Entity;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.GeneratedValue;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.GenerationType;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Id;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Inheritance;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.InheritanceType;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.SequenceGenerator;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Table;</span><br /><br /><span style="color: rgb(0,0,0);">@Entity</span><br /><span style="color: rgb(0,0,0);">@Inheritance(strategy</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">InheritanceType.SINGLE_TABLE)</span><br /><span style="color: rgb(0,0,0);">@DiscriminatorColumn(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"PERSON_TYPE"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">discriminatorType</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">DiscriminatorType.STRING)</span><br /><span style="color: rgb(0,0,0);">@DiscriminatorValue(</span><span style="color: rgb(42,0,255);">"PERSON"</span><span style="color: rgb(0,0,0);">)</span><br /><span style="color: rgb(0,0,0);">@Table(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"PERSON"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">schema</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"DATA_MODELLING"</span><span style="color: rgb(0,0,0);">)</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">Person</span> <span style="font-weight: bold; color: rgb(127,0,85);">implements</span> <span style="color: rgb(0,0,0);">java.io.Serializable</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">serialVersionUID</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">-2080047375791491221L;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">firstName;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">lastName;</span><br /><br /> <span style="color: rgb(0,0,0);">@Id</span><br /> <span style="color: rgb(0,0,0);">@GeneratedValue(strategy</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">GenerationType.SEQUENCE,</span> <span style="color: rgb(0,0,0);">generator</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"person_id_seq"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@SequenceGenerator(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"person_id_seq"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">sequenceName</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"person_id_seq"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"ID"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">getId()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setId(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">id)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.id</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"FIRST_NAME"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">50)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getFirstName()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">firstName;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setFirstName(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">firstName)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.firstName</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">firstName;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"LAST_NAME"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">50)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getLastName()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">lastName;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setLastName(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">lastName)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.lastName</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">lastName;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br />The updated <em>Author.java</em> must also register a <em>@DiscriminatorValue</em> but does not need to specify a primary key or table mapping because they are inherited from the base class.<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.data_modelling.domain;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.HashSet;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Set;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.CascadeType;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.DiscriminatorValue;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Entity;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.FetchType;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.OneToMany;</span><br /><br /><span style="color: rgb(0,0,0);">@Entity</span><br /><span style="color: rgb(0,0,0);">@DiscriminatorValue(</span><span style="color: rgb(42,0,255);">"AUTHOR"</span><span style="color: rgb(0,0,0);">)</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">Author</span> <span style="font-weight: bold; color: rgb(127,0,85);">extends</span> <span style="color: rgb(0,0,0);">Person</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">serialVersionUID</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">1792156832094030133L;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Set<Book></span> <span style="color: rgb(0,0,0);">books</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">HashSet<Book>();</span><br /><br /> <span style="color: rgb(0,0,0);">@OneToMany(cascade</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">CascadeType.ALL,</span> <span style="color: rgb(0,0,0);">fetch</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">FetchType.LAZY,</span> <span style="color: rgb(0,0,0);">mappedBy</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"author"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Set<Book></span> <span style="color: rgb(0,0,0);">getBooks()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">books;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setBooks(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Set<Book></span> <span style="color: rgb(0,0,0);">books)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.books</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">books;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br />We can demonstrate the relationship between Person and Author in our <em>AuthorTest.java</em>. These test cases show that an Author is a Person, but a Person is not necessarily an Author.<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.data_modelling.domain;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">org.junit.Assert.assertFalse;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">org.junit.Assert.assertTrue;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.List;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.SessionFactory;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.Test;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.runner.RunWith;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.beans.factory.annotation.Autowired;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.ContextConfiguration;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.junit4.SpringJUnit4ClassRunner;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.transaction.TransactionConfiguration;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.transaction.annotation.Transactional;</span><br /><br /><span style="color: rgb(0,0,0);">@RunWith(SpringJUnit4ClassRunner.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">)</span><br /><span style="color: rgb(0,0,0);">@ContextConfiguration(locations</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(42,0,255);">"/applicationContext.xml"</span> <span style="color: rgb(0,0,0);">})</span><br /><span style="color: rgb(0,0,0);">@TransactionConfiguration(transactionManager</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"txManager"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">defaultRollback</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">)</span><br /><span style="color: rgb(0,0,0);">@Transactional</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">AuthorTest</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="color: rgb(0,0,0);">@Autowired</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">SessionFactory</span> <span style="color: rgb(0,0,0);">sessionFactory;</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">anAuthorIsaPerson()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">cameronMcKenzie</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">createCameronMcKenzie();</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Person</span> <span style="color: rgb(0,0,0);">timMyer</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">createTimMyer();</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">List<?></span> <span style="color: rgb(0,0,0);">peopleWithaLastNameStartingWithM</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession()</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.createQuery(</span><span style="color: rgb(42,0,255);">"from Person person where person.lastName like 'M%'"</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.list();</span><br /> <span style="color: rgb(0,0,0);">assertTrue(peopleWithaLastNameStartingWithM.contains(cameronMcKenzie));</span><br /> <span style="color: rgb(0,0,0);">assertTrue(peopleWithaLastNameStartingWithM.contains(timMyer));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">notAllPeopleAreAuthors()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">cameronMcKenzie</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">createCameronMcKenzie();</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Person</span> <span style="color: rgb(0,0,0);">timMyer</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">createTimMyer();</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">List<?></span> <span style="color: rgb(0,0,0);">authorsWithaLastNameStartingWithM</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession()</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.createQuery(</span><span style="color: rgb(42,0,255);">"from Author author where author.lastName like 'M%'"</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.list();</span><br /> <span style="color: rgb(0,0,0);">assertTrue(authorsWithaLastNameStartingWithM.contains(cameronMcKenzie));</span><br /> <span style="color: rgb(0,0,0);">assertFalse(authorsWithaLastNameStartingWithM.contains(timMyer));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Person</span> <span style="color: rgb(0,0,0);">createTimMyer()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Person</span> <span style="color: rgb(0,0,0);">timMyer</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Person();</span><br /> <span style="color: rgb(0,0,0);">timMyer.setFirstName(</span><span style="color: rgb(42,0,255);">"Tim"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">timMyer.setLastName(</span><span style="color: rgb(42,0,255);">"Myer"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession().save(timMyer);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">timMyer;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">createCameronMcKenzie()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">cameronMcKenzie</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Author();</span><br /> <span style="color: rgb(0,0,0);">cameronMcKenzie.setFirstName(</span><span style="color: rgb(42,0,255);">"Cameron"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">cameronMcKenzie.setLastName(</span><span style="color: rgb(42,0,255);">"McKenzie"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession().save(cameronMcKenzie);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">cameronMcKenzie;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br />We now have a framework for easily registering new inter-related entities in our domain and for verifying the relationships between those entities.<br /><img src="http://farm4.static.flickr.com/3592/3410576457_1b552ba202_o.png" alt="The final project setup with the basic domain." />Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com0tag:blogger.com,1999:blog-106449775438946661.post-21611246507801845102009-03-22T14:04:00.000-07:002009-05-29T09:22:40.822-07:00Custom Inserts With Hibernate<h4>Goal:</h4><br />This article will present three techniques performing database insertions from Hibernate using sequence-generated primary keys. It is a continuation of <a href="http://timezra.blogspot.com/2008/11/hibernate-updates-and-oracle-stored.html">a previous post</a>, which describes techniques for calling Oracle stored procedures and functions for performing updates from Hibernate. Similar techniques may be used to perform custom inserts. These, however, present an interesting wrinkle in cases where the primary key for a row is generated directly by a database sequence. In order to keep the article current and to present an alternate build system, the project structure and libraries referenced are slightly different than those of the previous article in that Spring 3.0 and Maven2 are used. The use of Maven2 should simplify project configuration and library management.<br /><br /><h4>Setup a New M2 Project For Hibernate</h4><br />We can first create a simple M2 project in Eclipse, skipping archetype selection. We need not be concerned about the packaging and deployment of our code since we can verify our three approaches to Hibernate inserts with JUnit tests. We will also want to disable the project-specific Java Compiler settings to use Java 1.5 compliance for Hibernate annotations. The current default compliance for the M2 plug-in is 1.4.<br />We can configure our build for Spring, Hibernate, JUnit and <a href="http://forum.hibernate.org/viewtopic.php?p=2395418">Hibernate's dependencies</a>. Because our examples rely on Oracle, and because licensing issues prevent the distribution of the Oracle JDBC jars from the central Maven2 repository, we can <a href="http://www.coderanch.com/t/109193/Ant-Maven-Other-Build-Tools/Oracle-Drivers-using-Maven">install the ojdbc14 driver in our local Maven2 repository</a> and add it as a dependency in the project configuration.<br />To install the driver, we will run the following snippet from the command-line<br /> mvn install:install-file -DgroupId=com.oracle -DartifactId=ojdbc14 -Dversion=10.2.0.2.0 -Dpackaging=jar -Dfile=/path/to/ojdbc14.jar<br /><br />Our <em>pom.xml</em> should look like this:<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0"</span> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span><br /> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span>4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>timezra.blog.hibernate.custom_insert<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>timezra.blog.hibernate.custom_insert<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span>timezra.blog.hibernate.custom_insert<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>0.0.1-SNAPSHOT<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">description</span><span style="color: rgb(0,128,128);">></span>Hibernate Inserts Example<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">description</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>org.springframework.transaction<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.0.M2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>org.springframework.orm<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.0.M2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.hibernate<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>hibernate-annotations<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.4.0.GA<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.slf4j<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>slf4j-log4j12<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.5.2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>javassist<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>javassist<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.4.GA<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>cglib<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>cglib<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>2.2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>commons-dbcp<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>commons-dbcp<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.2.2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>com.oracle<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>ojdbc14<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>10.2.0.2.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>junit<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>junit<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>4.5<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>org.springframework.test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.0.M2<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repositories</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>SpringSource Enterprise Bundle Repository - External Bundle Milestones<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://repository.springsource.com/maven/bundles/milestone<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://repository.springsource.com/maven/bundles/release<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>SpringSource Enterprise Bundle Repository - External Bundle Releases<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://repository.springsource.com/maven/bundles/external<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repositories</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><br />Now that we have a project layout, we can configure Spring to manage our datasources and Hibernate transactions. A simple configuration in a <em>src/main/resources/applicationContext.xml</em> file would look like this:<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">beans</span> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/beans"</span><br /> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span> <span style="color: rgb(127,0,127);">xmlns:tx</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/tx"</span><br /> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/beans<br /> http://www.springframework.org/schema/beans/spring-beans.xsd<br /> http://www.springframework.org/schema/tx<br /> http://www.springframework.org/schema/tx/spring-tx.xsd"</span><span style="color: rgb(0,128,128);">></span><br /> <br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"dataSource"</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.apache.commons.dbcp.BasicDataSource"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"driverClassName"</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span>oracle.jdbc.driver.OracleDriver<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"username"</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span>custom_insert<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"password"</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span>custom_insert<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"url"</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span>jdbc:oracle:thin:@localhost:1521:orcl<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">value</span><span style="color: rgb(0,128,128);">></span><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"sessionFactory"</span><br /> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.orm.hibernate3.LocalSessionFactoryBean"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"dataSource"</span> <span style="color: rgb(127,0,127);">ref</span>=<span style="font-style: italic; color: rgb(42,0,255);">"dataSource"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"configLocation"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"classpath:/hibernate.cfg.xml"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"configurationClass"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.hibernate.cfg.AnnotationConfiguration"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernateProperties"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">props</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.show_sql"</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.format_sql"</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.generate_statistics"</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.use_sql_comments"</span><span style="color: rgb(0,128,128);">></span>true<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.hbm2ddl.auto"</span><span style="color: rgb(0,128,128);">></span>create<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.dialect"</span><span style="color: rgb(0,128,128);">></span>org.hibernate.dialect.Oracle10gDialect<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">prop</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"hibernate.query.factory_class"</span><span style="color: rgb(0,128,128);">></span>org.hibernate.hql.classic.ClassicQueryTranslatorFactory<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">prop</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">props</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"txManager"</span><br /> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.orm.hibernate3.HibernateTransactionManager"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"sessionFactory"</span> <span style="color: rgb(127,0,127);">ref</span>=<span style="font-style: italic; color: rgb(42,0,255);">"sessionFactory"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">tx:annotation-driven</span> <span style="color: rgb(127,0,127);">transaction-manager</span>=<span style="font-style: italic; color: rgb(42,0,255);">"txManager"</span><span style="color: rgb(0,128,128);">/></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">beans</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br /><h4>Create a Schema</h4><br />For this example, we can create a pristine user in our database. If you choose an existing schema, be aware that the <b>hibernate.hbm2ddl.auto</b> property in the <em>applicationContext.xml</em> will re-create the database any time the Hibernate container starts.<br />We will run these commands from sqlplus to create our user:<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /> sqlplus connect as SYSDBA<br /> create user custom_insert identified by custom_insert default tablespace users temporary tablespace temp;<br /> grant connect, resource to custom_insert;<br /> grant create table to custom_insert;<br /></span><br /></div><br /><br /><h4>Create a Domain Object</h4><br />With Spring and Maven2 configured and a schema available in Oracle, we can create our domain, which should look familiar from the previous article. The meta-data in the <em>Author.java</em> file maps the Object to a database table.<br />Our <em>src/main/resources/hibernate.cfg.xml</em> file can be as simple as this for a single domain Object:<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><!</span><span style="color: rgb(63,127,127);">DOCTYPE</span> <span style="color: rgb(0,128,128);">hibernate-configuration</span> <span style="color: rgb(128,128,128);">PUBLIC</span><br /> <span style="color: rgb(0,128,128);">"-//Hibernate/Hibernate Configuration DTD 3.0//EN"</span><br /> <span style="color: rgb(63,127,95);">"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">hibernate-configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">session-factory</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">mapping</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"timezra.blog.hibernate.custom_insert.domain.Author"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">session-factory</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">hibernate-configuration</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><br />The first configuration of our <em>Author.java</em> domain Object can use Hibernate's built-in support for a sequence-generated ID.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.custom_insert.domain;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Column;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Entity;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.GeneratedValue;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.GenerationType;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Id;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.SequenceGenerator;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">javax.persistence.Table;</span><br /><br /><span style="color: rgb(0,0,0);">@Entity</span><br /><span style="color: rgb(0,0,0);">@Table(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"AUTHOR"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">schema</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"CUSTOM_INSERT"</span><span style="color: rgb(0,0,0);">)</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">Author</span> <span style="font-weight: bold; color: rgb(127,0,85);">implements</span> <span style="color: rgb(0,0,0);">java.io.Serializable</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">long</span> <span style="color: rgb(0,0,0);">serialVersionUID</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">-6270202393794713117L;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">firstName;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">lastName;</span><br /><br /> <span style="color: rgb(0,0,0);">@Id</span><br /> <span style="color: rgb(0,0,0);">@GeneratedValue(strategy</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">GenerationType.SEQUENCE,</span> <span style="color: rgb(0,0,0);">generator</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"author_id_seq"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@SequenceGenerator(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"author_id_seq"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">sequenceName</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"author_id_seq"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"ID"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">getId()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setId(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">id)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.id</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"FIRST_NAME"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">50)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getFirstName()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">firstName;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setFirstName(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">firstName)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.firstName</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">firstName;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"LAST_NAME"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">length</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">50)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getLastName()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">lastName;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setLastName(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">lastName)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.lastName</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">lastName;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br />We can start with a simple suite, <em>AuthorTest.java</em>, to determine whether, after we perform an insertion into the database, the same Object will be retrieved using an HQL a query. The test will also verify that our configuration is correct, and it will build the structures in our database, i.e., the domain table and the sequence.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.custom_insert.domain;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">org.junit.Assert.assertEquals;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="color: rgb(0,0,0);">org.junit.Assert.assertSame;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Collection;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.SessionFactory;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.Test;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.runner.RunWith;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.beans.factory.annotation.Autowired;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.ContextConfiguration;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.junit4.SpringJUnit4ClassRunner;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.transaction.TransactionConfiguration;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.transaction.annotation.Transactional;</span><br /><br /><span style="color: rgb(0,0,0);">@RunWith(SpringJUnit4ClassRunner.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">)</span><br /><span style="color: rgb(0,0,0);">@ContextConfiguration(locations</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(42,0,255);">"/applicationContext.xml"</span> <span style="color: rgb(0,0,0);">})</span><br /><span style="color: rgb(0,0,0);">@TransactionConfiguration(transactionManager</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"txManager"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">defaultRollback</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">)</span><br /><span style="color: rgb(0,0,0);">@Transactional</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">AuthorTest</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="color: rgb(0,0,0);">@Autowired</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">SessionFactory</span> <span style="color: rgb(0,0,0);">sessionFactory;</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">insertAnAuthor()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">author</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Author();</span><br /> <span style="color: rgb(0,0,0);">author.setFirstName(</span><span style="color: rgb(42,0,255);">"Cameron"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">author.setLastName(</span><span style="color: rgb(42,0,255);">"McKenzie"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">author.setId(0);</span><br /> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession().save(author);</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Collection<Author></span> <span style="color: rgb(0,0,0);">authors</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">findByLastName(</span><span style="color: rgb(42,0,255);">"McKenzie"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">assertEquals(1,</span> <span style="color: rgb(0,0,0);">authors.size());</span><br /> <span style="color: rgb(0,0,0);">assertSame(author,</span> <span style="color: rgb(0,0,0);">authors.iterator().next());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@SuppressWarnings(</span><span style="color: rgb(42,0,255);">"unchecked"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Collection<Author></span> <span style="color: rgb(0,0,0);">findByLastName(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">lastName)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession()</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.createQuery(</span><span style="color: rgb(42,0,255);">"from Author author where author.lastName = :vLastName"</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(63,127,95);">// <br /></span> <span style="color: rgb(0,0,0);">.setParameter(</span><span style="color: rgb(42,0,255);">"vLastName"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">lastName)</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.list();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br /><h4>Generate the Primary Key With a Trigger</h4><br />Now that our database is setup, we can create a custom trigger to populate the Author ID directly in the database, instead of relying on Hibernate to populate this value. <br />In order to prevent our trigger from disappearing every time the Hibernate container starts, we must set the <b>hibernate.hbm2ddl.auto</b> property in the <em>applicationContext.xml</em> to <b>update</b>.<br /><br />The <em>before_author</em> trigger will use the same <em>author_id_seq</em>, now that Hibernate has created it for us, but it will be managed directly by Oracle.<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /><span style="font-weight: bold; color: rgb(127,0,85);">CREATE OR REPLACE TRIGGER</span> before_author <span style="font-weight: bold; color: rgb(127,0,85);">BEFORE INSERT ON</span> author<br /><span style="font-weight: bold; color: rgb(127,0,85);">FOR EACH ROW</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">BEGIN</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">SELECT</span> author_id_seq.nextval <span style="font-weight: bold; color: rgb(127,0,85);">INTO</span> :<span style="font-weight: bold; color: rgb(127,0,85);">NEW</span>.id <span style="font-weight: bold; color: rgb(127,0,85);">FROM DUAL;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">END</span>;<br /></span><br /></div><br /><br />In order to retrieve this primary key, we can use a <a href="http://forum.hibernate.org/viewtopic.php?p=2379010"><em>TriggerAssignedIdentityGenerator.java</em></a>, which will return the value of the primary key after the prepared statement is executed through JDBC. This method relies on implementation details of Oracle's JDBC driver, so only time will tell how fragile it may be. Also note that only one database hit is required for this insertion, but in order to retrieve other trigger-generated non-primary key values, a session#flush and #refresh may be required which will create extra network and database traffic.<br /><div style="overflow:auto;width:100%;height:750px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.custom_insert.domain;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.io.Serializable;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.sql.PreparedStatement;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.sql.SQLException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.HibernateException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.dialect.Dialect;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.engine.SessionImplementor;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.id.AbstractPostInsertGenerator;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.id.IdentifierGeneratorFactory;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.id.PostInsertIdentityPersister;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.id.SequenceIdentityGenerator.NoCommentsInsert;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.id.insert.AbstractReturningDelegate;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.id.insert.IdentifierGeneratingInsert;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">TriggerAssignedIdentityGenerator</span> <span style="font-weight: bold; color: rgb(127,0,85);">extends</span> <span style="color: rgb(0,0,0);">AbstractPostInsertGenerator</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">InsertGeneratedIdentifierDelegate</span> <span style="color: rgb(0,0,0);">getInsertGeneratedIdentifierDelegate(</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">PostInsertIdentityPersister</span> <span style="color: rgb(0,0,0);">persister,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Dialect</span> <span style="color: rgb(0,0,0);">dialect,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">isGetGeneratedKeysEnabled)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">HibernateException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Delegate(persister,</span> <span style="color: rgb(0,0,0);">dialect);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">Delegate</span> <span style="font-weight: bold; color: rgb(127,0,85);">extends</span> <span style="color: rgb(0,0,0);">AbstractReturningDelegate</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Dialect</span> <span style="color: rgb(0,0,0);">dialect;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String[]</span> <span style="color: rgb(0,0,0);">keyColumns;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Delegate(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">PostInsertIdentityPersister</span> <span style="color: rgb(0,0,0);">persister,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Dialect</span> <span style="color: rgb(0,0,0);">dialect)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">super</span><span style="color: rgb(0,0,0);">(persister);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.dialect</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">dialect;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.keyColumns</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">getPersister().getRootTableKeyColumnNames();</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(keyColumns.length</span> <span style="color: rgb(0,0,0);">></span> <span style="color: rgb(0,0,0);">1)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">throw</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">HibernateException(</span><span style="color: rgb(42,0,255);">"TriggerAssignedIdentityGenerator cannot be used with multi-column keys"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">IdentifierGeneratingInsert</span> <span style="color: rgb(0,0,0);">prepareIdentifierGeneratingInsert()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">NoCommentsInsert(dialect);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Override</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">protected</span> <span style="color: rgb(0,0,0);">PreparedStatement</span> <span style="color: rgb(0,0,0);">prepare(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">insertSQL,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">SessionImplementor</span> <span style="color: rgb(0,0,0);">session)</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">SQLException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">session.getBatcher().prepareStatement(insertSQL,</span> <span style="color: rgb(0,0,0);">keyColumns);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Override</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">protected</span> <span style="color: rgb(0,0,0);">Serializable</span> <span style="color: rgb(0,0,0);">executeAndExtract(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">PreparedStatement</span> <span style="color: rgb(0,0,0);">insert)</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">SQLException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">insert.executeUpdate();</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">IdentifierGeneratorFactory.getGeneratedIdentity(insert.getGeneratedKeys(),</span> <span style="color: rgb(0,0,0);">getPersister()</span><br /> <span style="color: rgb(0,0,0);">.getIdentifierType());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span></span><br /></div><br /><br /><em>Author.java</em> must be updated to use the new ID generator, so that the primary key can be properly set.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br />....<br /> <span style="color: rgb(0,0,0);">@Id</span><br /> <span style="color: rgb(0,0,0);">@GeneratedValue(generator</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"triggerAssigned"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@GenericGenerator(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"triggerAssigned"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">strategy</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"timezra.blog.hibernate.custom_insert.domain.TriggerAssignedIdentityGenerator"</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="color: rgb(0,0,0);">@Column(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"ID"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">nullable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">getId()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">id;</span><br /> <span style="color: rgb(0,0,0);">}</span><br />....<br /></span><br /></div><br /><br />From our <em>AuthorTest.java</em>, we can verify that the expected Sequence is indeed used to generate the primary key.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br />....<br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">theAuthorsIdIsGeneratedFromASequence()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Session</span> <span style="color: rgb(0,0,0);">session</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession();</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">cameronMcKenzie</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">createCameronMcKenzie();</span><br /> <span style="color: rgb(0,0,0);">session.save(cameronMcKenzie);</span><br /> <span style="color: rgb(0,0,0);">assertEquals(getTheCurrentAuthorSequenceValue().intValue(),</span> <span style="color: rgb(0,0,0);">cameronMcKenzie.getId());</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">christianBauer</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">createChristianBauer();</span><br /> <span style="color: rgb(0,0,0);">session.save(christianBauer);</span><br /> <span style="color: rgb(0,0,0);">assertEquals(getTheCurrentAuthorSequenceValue().intValue(),</span> <span style="color: rgb(0,0,0);">christianBauer.getId());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">BigDecimal</span> <span style="color: rgb(0,0,0);">getTheCurrentAuthorSequenceValue()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">(BigDecimal)</span> <span style="color: rgb(0,0,0);">sessionFactory.getCurrentSession()</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.createSQLQuery(</span><span style="color: rgb(42,0,255);">"select author_id_seq.currval from dual"</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(63,127,95);">//<br /></span> <span style="color: rgb(0,0,0);">.uniqueResult();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">createCameronMcKenzie()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">cameronMcKenzie</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Author();</span><br /> <span style="color: rgb(0,0,0);">cameronMcKenzie.setFirstName(</span><span style="color: rgb(42,0,255);">"Cameron"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">cameronMcKenzie.setLastName(</span><span style="color: rgb(42,0,255);">"McKenzie"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">cameronMcKenzie;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">createChristianBauer()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Author</span> <span style="color: rgb(0,0,0);">christianBauer</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Author();</span><br /> <span style="color: rgb(0,0,0);">christianBauer.setFirstName(</span><span style="color: rgb(42,0,255);">"Christian"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">christianBauer.setLastName(</span><span style="color: rgb(42,0,255);">"Bauer"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">christianBauer;</span><br /> <span style="color: rgb(0,0,0);">}</span><br />....<br /></span><br /></div><br /><br /><h4>Insert With a Stored Procedure</h4><br />Suppose we have a restriction against using triggers, or that we are restricted from calling <em>INSERT</em> statements directly. <br />We can drop the <em>after_author</em> trigger and create a new <em>insert_author</em> stored procedure that essentially performs the same task. This stored procedure strategy can be expanded to include the removal of after or statement triggers, as well.<br /><div style="overflow:auto;width:80%;padding:5px;color:white;background-color:black;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br /><span style="font-weight: bold; color: rgb(127,0,85);">DROP TRIGGER</span> before_author;<br /><span style="font-weight: bold; color: rgb(127,0,85);">CREATE OR REPLACE PROCEDURE</span> insert_author<br />( vFirstName <span style="font-weight: bold; color: rgb(127,0,85);">IN</span> author.first_name%<span style="font-weight: bold; color: rgb(127,0,85);">type</span>,<br /> vLastName <span style="font-weight: bold; color: rgb(127,0,85);">IN</span> author.last_name%<span style="font-weight: bold; color: rgb(127,0,85);">type</span>,<br /> vId <span style="font-weight: bold; color: rgb(127,0,85);">OUT</span> author.id%<span style="font-weight: bold; color: rgb(127,0,85);">type</span> ) <span style="font-weight: bold; color: rgb(127,0,85);">IS</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">BEGIN</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">INSERT INTO</span> author<br /> ( first_name, last_name, id )<br /> <span style="font-weight: bold; color: rgb(127,0,85);">VALUES</span><br /> ( vFirstName, vLastName, author_id_seq.<span style="font-weight: bold; color: rgb(127,0,85);">nextval</span> )<br /> <span style="font-weight: bold; color: rgb(127,0,85);">RETURNING</span> id <span style="font-weight: bold; color: rgb(127,0,85);">INTO</span> vId;<br /><span style="font-weight: bold; color: rgb(127,0,85);">END</span> insert_author;<br /></span><br /></div><br />Note the way the procedure reports the generated primary key: we must include an <b>OUT</b> argument in the parameter signature and the insertion statement must return the key using this argument.<br /><br />The <em>Author.java</em> domain Object can now include a declaration that the stored procedure will be used for insertions, much the same as we used the @SQLUpdate declaration in the previous article.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><br />....<br /><span style="color: rgb(0,0,0);">@Entity</span><br /><span style="color: rgb(0,0,0);">@org.hibernate.annotations.SQLInsert(sql</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"{call insert_author(:vFirstName, :vLastName, :vId)}"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">callable</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">)</span><br /><span style="color: rgb(0,0,0);">@Table(name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"AUTHOR"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(0,0,0);">schema</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(42,0,255);">"CUSTOM_INSERT"</span><span style="color: rgb(0,0,0);">)</span><br />....<br /></span><br /></div><br />Note the final parameter in the CallableStatement: Hibernate will populate all the statement parameters by index; if we need to add more parameters to our procedure, they must come after all the non-generated fields in our domain Object.<br /><br />Our <em>TriggerAssignedIdentityGenerator</em> will not be able to retrieve the primary key, nor will it know enough to register that the key is contained in the <b>OUT</b> parameter. A more appropriate class could be called <em>ProcedureAssignedIdentityGenerator.java</em> and would look like this:<br /><div style="overflow:auto;width:100%;height:750px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.hibernate.custom_insert.domain;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.io.Serializable;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.sql.CallableStatement;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.sql.PreparedStatement;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.sql.SQLException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.sql.Types;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.HibernateException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.dialect.Dialect;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.engine.SessionImplementor;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.id.AbstractPostInsertGenerator;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.id.PostInsertIdentityPersister;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.id.SequenceIdentityGenerator.NoCommentsInsert;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.id.insert.AbstractReturningDelegate;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.id.insert.IdentifierGeneratingInsert;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.hibernate.id.insert.InsertGeneratedIdentifierDelegate;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">ProcedureAssignedIdentityGenerator</span> <span style="font-weight: bold; color: rgb(127,0,85);">extends</span> <span style="color: rgb(0,0,0);">AbstractPostInsertGenerator</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">InsertGeneratedIdentifierDelegate</span> <span style="color: rgb(0,0,0);">getInsertGeneratedIdentifierDelegate(</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">PostInsertIdentityPersister</span> <span style="color: rgb(0,0,0);">persister,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Dialect</span> <span style="color: rgb(0,0,0);">dialect,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">boolean</span> <span style="color: rgb(0,0,0);">isGetGeneratedKeysEnabled)</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">HibernateException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Delegate(persister,</span> <span style="color: rgb(0,0,0);">dialect);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">Delegate</span> <span style="font-weight: bold; color: rgb(127,0,85);">extends</span> <span style="color: rgb(0,0,0);">AbstractReturningDelegate</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Dialect</span> <span style="color: rgb(0,0,0);">dialect;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">Delegate(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">PostInsertIdentityPersister</span> <span style="color: rgb(0,0,0);">persister,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Dialect</span> <span style="color: rgb(0,0,0);">dialect)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">super</span><span style="color: rgb(0,0,0);">(persister);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.dialect</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">dialect;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">IdentifierGeneratingInsert</span> <span style="color: rgb(0,0,0);">prepareIdentifierGeneratingInsert()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">NoCommentsInsert(dialect);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Override</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">protected</span> <span style="color: rgb(0,0,0);">PreparedStatement</span> <span style="color: rgb(0,0,0);">prepare(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">insertSQL,</span> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">SessionImplementor</span> <span style="color: rgb(0,0,0);">session)</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">SQLException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">session.getBatcher().prepareCallableStatement(insertSQL);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Override</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">protected</span> <span style="color: rgb(0,0,0);">Serializable</span> <span style="color: rgb(0,0,0);">executeAndExtract(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">PreparedStatement</span> <span style="color: rgb(0,0,0);">insert)</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">SQLException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">CallableStatement</span> <span style="color: rgb(0,0,0);">cs</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">(CallableStatement)</span> <span style="color: rgb(0,0,0);">insert;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="font-weight: bold; color: rgb(127,0,85);">int</span> <span style="color: rgb(0,0,0);">indexOfTheId</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">cs.getParameterMetaData().getParameterCount();</span><br /> <span style="color: rgb(0,0,0);">cs.registerOutParameter(indexOfTheId,</span> <span style="color: rgb(0,0,0);">Types.NUMERIC);</span><br /> <span style="color: rgb(0,0,0);">insert.executeUpdate();</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">cs.getInt(indexOfTheId);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span></span><br /></div><br />Note that the primary key in this case must be an int or Integer and it must appear as the final parameter in the CallableStatement.<br /><br />When we run our tests again, there should be no change in the results. The database Sequence still generates the Author ID. If we examine the generated SQL (from the console output), we will see that the stored procedure is invoked.<br /><br />Using this project structure, we can now continue to add domain Objects and we can benefit from a mix of both Hibernate and Oracle-specific features.<br /><img src="http://farm4.static.flickr.com/3573/3377059744_0e1f33b5d5_o.png" alt="The final project layout in Eclipse." >Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com3tag:blogger.com,1999:blog-106449775438946661.post-32089352638595270802009-03-01T17:23:00.000-08:002009-05-29T09:34:33.410-07:00Spring 3.0 Quartz Batch With Maven2<h4>Goal</h4><br />The purpose of this entry is to provide a short tutorial for setting up a Maven2 project that uses Spring 3.0 to schedule a Quartz batch job, to inject Spring-managed beans into this Quartz-managed job, to use Spring to test the job, and to setup a distributable, runnable assembly for the project. <br /><br /><h4>Setup a New Maven Project</h4><br />Setting up a new Maven project in Eclipse with the <a href="http://m2eclipse.codehaus.org/">m2eclipse plug-in</a> is straightforward, even without the fancy <em>pom</em> editors. For this example, we can create a simple project (skip archetype selection) and package the target as a <em>jar</em>.<br /><div style="overflow:auto;width:65%;"><br /> <img src="http://farm4.static.flickr.com/3550/3320939552_e878d341fe.jpg" alt="New Maven Project" /><br /></div><br /><br /><h4>Add Repositories and Register Dependencies</h4><br />Because Spring 3.0.0.M1 is currently not available in the main Maven repositories, we will need to add custom repositories to our <em>pom.xml</em> (Thanks to <a href="http://blog.springsource.com/2008/12/05/spring-framework-30-m1-released/#comment-131869">Chris Beams</a> for his instructions).<br />We are particularly interested in <em>org.springframework.context.support</em>, which contains the Spring-Quartz bridge that has been separated out from the core <em>spring.jar</em> between Spring 2.5 and 3.0; <em>org.springframework.transaction</em>, which the Spring-Quartz bridge depends on; <em>commons-collections</em>, which the Spring-Quartz bridge also depends on; and <em>quartz</em> from <a href="http://www.opensymphony.com/">OpenSymphony</a>.<br />Our new <em>pom.xml</em> should look like this:<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">project</span> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0"</span> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span><br /> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span>4.0.0<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">modelVersion</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>timezra.blog.spring_batch<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>timezra.blog.spring_batch<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span>timezra.blog.spring_batch<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">name</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>0.0.1-SNAPSHOT<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">description</span><span style="color: rgb(0,128,128);">></span>Spring Batch Example<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">description</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>org.springframework.context.support<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.0.M1<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>org.springframework.transaction<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.0.M1<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.opensymphony.quartz<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>quartz<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>1.6.1<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>commons-collections<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>commons-collections<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.2.1<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependencies</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repositories</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>SpringSource Enterprise Bundle Repository - External Bundle Milestones<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://repository.springsource.com/maven/bundles/milestone<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>SpringSource Enterprise Bundle Repository - SpringSource Bundle Releases<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://repository.springsource.com/maven/bundles/release<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span>SpringSource Enterprise Bundle Repository - External Bundle Releases<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">id</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span>http://repository.springsource.com/maven/bundles/external<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">url</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repository</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">repositories</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">project</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><b>NB</b>: As Spring 3.0.0 becomes generally available, registering custom repositories will no longer be necessary, and the necessary versions of the Spring dependencies may change.<br /><br /><h4>Create the Spring Application</h4><br />We are now ready to register a batch job with Spring in a <em>/src/main/resources/applicationContext.xml</em> file. This registration requires three components: a job declaration, a trigger that depends on the registered job, and a scheduler that depends on the trigger. In our case, we would also like to declare a separate Spring-managed bean and inject that as a dependency into the job. A sample <em>applicationContext.xml</em> would look like this, where our (unimplemented) job will run every five seconds:<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span> <span style="color: rgb(127,0,127);">encoding</span>=<span style="font-style: italic; color: rgb(42,0,255);">"UTF-8"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">beans</span> <span style="color: rgb(127,0,127);">xmlns</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/beans"</span><br /> <span style="color: rgb(127,0,127);">xmlns:xsi</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/2001/XMLSchema-instance"</span><br /> <span style="color: rgb(127,0,127);">xsi:schemaLocation</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.springframework.org/schema/beans<br /> http://www.springframework.org/schema/beans/spring-beans.xsd"</span><span style="color: rgb(0,128,128);">></span><br /><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"myBean"</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"timezra.blog.spring_batch.MyBean"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"name"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"My Name"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobDetail"</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.scheduling.quartz.JobDetailBean"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobClass"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"timezra.blog.spring_batch.MyJob"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobDataAsMap"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">map</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">entry</span> <span style="color: rgb(127,0,127);">key</span>=<span style="font-style: italic; color: rgb(42,0,255);">"myBean"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">ref</span> <span style="color: rgb(127,0,127);">bean</span>=<span style="font-style: italic; color: rgb(42,0,255);">"myBean"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">entry</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">map</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobDetailTrigger"</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.scheduling.quartz.CronTriggerBean"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobDetail"</span> <span style="color: rgb(127,0,127);">ref</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobDetail"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"cronExpression"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"0/5 * * * * ?"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"schedulerFactoryBean"</span><br /> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.scheduling.quartz.SchedulerFactoryBean"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"triggers"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">list</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">ref</span> <span style="color: rgb(127,0,127);">bean</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobDetailTrigger"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">list</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">beans</span><span style="color: rgb(0,128,128);">></span><br /></span><br /></div><br /><b>NB</b>: Spring injects the <em>myBean</em> dependency through the <em>jobDataAsMap</em> property on the <em>JobDetailBean</em>.<br /><br />The <em>MyBean.java</em> implementation can be as simple as<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.spring_batch;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">MyBean</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">name;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">getName()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">return</span> <span style="color: rgb(0,0,0);">name;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setName(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">name)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.name</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">name;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br /><em>MyJob.java</em> contains the logic for our batch job.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.spring_batch;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.quartz.JobExecutionContext;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.quartz.JobExecutionException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.quartz.StatefulJob;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.scheduling.quartz.QuartzJobBean;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">MyJob</span> <span style="font-weight: bold; color: rgb(127,0,85);">extends</span> <span style="color: rgb(0,0,0);">QuartzJobBean</span> <span style="font-weight: bold; color: rgb(127,0,85);">implements</span> <span style="color: rgb(0,0,0);">StatefulJob</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">MyBean</span> <span style="color: rgb(0,0,0);">myBean;</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">MyJob()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">System.out.println(</span><span style="color: rgb(42,0,255);">"MyJob.MyJob()"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Override</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">protected</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">executeInternal(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">JobExecutionContext</span> <span style="color: rgb(0,0,0);">context)</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">JobExecutionException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">System.out.println(</span><span style="color: rgb(42,0,255);">"myBean's name=["</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">myBean.getName()</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(42,0,255);">"] and its instance is ["</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">myBean</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(42,0,255);">"]."</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">setMyBean(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">MyBean</span> <span style="color: rgb(0,0,0);">myBean)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">this</span><span style="color: rgb(0,0,0);">.myBean</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">myBean;</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><b>NB</b>: For this example, we have created a mutator so <em>myBean</em> can be injected, we print whenever a new Job is constructed, and when the job runs, we print the name of <em>myBean</em> and its instance.<br /><br /><h4>Create a Main Runner</h4><br />We can easily create a runner for the batch job just to get a feel for what is happening as the Spring container is initialized, as Spring starts the Quartz scheduler and as the Quartz scheduler runs. We simply need to create an <em>ApplicationContext</em> with our <em>applicationContext.xml</em>.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.spring_batch;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.context.support.ClassPathXmlApplicationContext;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">Main</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">main(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String[]</span> <span style="color: rgb(0,0,0);">args)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">ClassPathXmlApplicationContext(</span><span style="color: rgb(42,0,255);">"/applicationContext.xml"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br />If we run this file as a java application, we see that every five seconds, a new instance of our job is created (which is not necessarily surprising) and the job is executed with the same instance of <em>myBean</em> (which should be anticipated).<br /><br /><h4>Scope MyBean as Prototype</h4><br />Suppose we want a new instance of <em>myBean</em> for each execution of the job. If Spring were managing the lifecycle of the job instances, this might be as straightforward as declaring the <em>myBean</em>'s scope as <em>prototype</em> in the <em>applicationContext.xml</em>. <br />What happens? The <em>myBean</em> instance that is printed for each run of the job is the same. Quartz, not Spring, is managing the construction of these jobs. <br />What happens if we specify that the <em>JobDetailBean</em> is a <em>prototype</em>? The instance of <em>myBean</em> in the job is still the same.<br />Fortunately, it is possible to get a handle on the Spring <em>ApplicationContext</em> from the job by changing only a few lines of code in our <em>applicationContext.xml</em> and in <em>MyJob.java</em>.<br /><br /><h4>Add the Application Context to the Job Data Map</h4><br />To inject the <em>ApplicationContext</em> into a Job, we need to specify a key for it, so we can retrieve it from the <em>JobExecutionContext</em>'s data map. We also will no longer inject the dependency into the job since we will retrieve it directly from the <em>ApplicationContext</em>.<br />The updated <em>applicationContext.xml</em> should look like this:<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobDetail"</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.scheduling.quartz.JobDetailBean"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobClass"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"timezra.blog.spring_batch.MyJob"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"applicationContextJobDataKey"</span> <span style="color: rgb(127,0,127);">value</span>=<span style="font-style: italic; color: rgb(42,0,255);">"applicationContext"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /> ....</span><br /></div><br /><b>NB</b>: we can set the <em>ApplicationContext</em>'s key by specifying the <em>applicationContextJobDataKey</em> property for the <em>JobDetailBean</em>.<br /><br />The updated <em>MyJob.java</em> now retrieves <em>myBean</em> directly from the <em>ApplicationContext</em>.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.spring_batch;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.quartz.JobExecutionContext;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.quartz.JobExecutionException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.quartz.StatefulJob;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.beans.factory.BeanFactory;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.scheduling.quartz.QuartzJobBean;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">MyJob</span> <span style="font-weight: bold; color: rgb(127,0,85);">extends</span> <span style="color: rgb(0,0,0);">QuartzJobBean</span> <span style="font-weight: bold; color: rgb(127,0,85);">implements</span> <span style="color: rgb(0,0,0);">StatefulJob</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="color: rgb(0,0,0);">MyJob()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">System.out.println(</span><span style="color: rgb(42,0,255);">"MyJob.MyJob()"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="color: rgb(0,0,0);">@Override</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">protected</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">executeInternal(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">JobExecutionContext</span> <span style="color: rgb(0,0,0);">context)</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">JobExecutionException</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">BeanFactory</span> <span style="color: rgb(0,0,0);">applicationContext</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">(BeanFactory)</span> <span style="color: rgb(0,0,0);">context.getMergedJobDataMap().get(</span><span style="color: rgb(42,0,255);">"applicationContext"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">MyBean</span> <span style="color: rgb(0,0,0);">myBean</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">(MyBean)</span> <span style="color: rgb(0,0,0);">applicationContext.getBean(</span><span style="color: rgb(42,0,255);">"myBean"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">System.out.println(</span><span style="color: rgb(42,0,255);">"myBean's name=["</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">myBean.getName()</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(42,0,255);">"] and its instance is ["</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(0,0,0);">myBean</span> <span style="color: rgb(0,0,0);">+</span> <span style="color: rgb(42,0,255);">"]."</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br /><h4>Test The Batch Job Instance</h4><br />As we have demonstrated, Spring is not managing the lifecycle of our quartz job directly, only of the <em>JobDetailBean</em>. Whenever I test a Spring-managed bean, I personally prefer that Spring injects an instance of the bean into the test, rather than to call the constructor for that bean directly. After all, the bean under test is a dependency of the test case itself.<br />While it may not be obvious how we can get an instance of our job inside the test case for that job, it is not difficult, only slightly roundabout. We must specify a <em>JobFactory</em> for the <em>SchedulerFactoryBean</em> explicitly in our <em>applicationContext.xml</em>.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobFactory"</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.scheduling.quartz.SpringBeanJobFactory"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">bean</span> <span style="color: rgb(127,0,127);">id</span>=<span style="font-style: italic; color: rgb(42,0,255);">"schedulerFactoryBean"</span><br /> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"org.springframework.scheduling.quartz.SchedulerFactoryBean"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"triggers"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">list</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">ref</span> <span style="color: rgb(127,0,127);">bean</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobDetailTrigger"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">list</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">property</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">property</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobFactory"</span> <span style="color: rgb(127,0,127);">ref</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jobFactory"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">bean</span><span style="color: rgb(0,128,128);">></span><br /> ....</span><br /></div><br /><br />We will also declare a couple of new test-scoped dependencies in our <em>pom.xml</em>.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>junit<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>junit<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>4.5<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span>test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">scope</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span>org.springframework<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">groupId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>org.springframework.test<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span>3.0.0.M1<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">version</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">dependency</span><span style="color: rgb(0,128,128);">></span><br /> ....</span><br /></div><br /><br />Finally, we can create a JUnit test case, <em>MyJobTest.java</em>, that simulates the triggering of the job. Whether or not wiring together the scheduler, trigger and factory is better than instantiating the job directly depends on your own preference. This technique is simply one approach.<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.spring_batch;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Date;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.Test;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.junit.runner.RunWith;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.quartz.Job;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.quartz.JobExecutionContext;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.quartz.impl.calendar.CronCalendar;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.quartz.spi.TriggerFiredBundle;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.beans.factory.annotation.Autowired;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.scheduling.quartz.CronTriggerBean;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.scheduling.quartz.SchedulerFactoryBean;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.scheduling.quartz.SpringBeanJobFactory;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.ContextConfiguration;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.springframework.test.context.junit4.SpringJUnit4ClassRunner;</span><br /><br /><span style="color: rgb(0,0,0);">@RunWith(SpringJUnit4ClassRunner.</span><span style="font-weight: bold; color: rgb(127,0,85);">class</span><span style="color: rgb(0,0,0);">)</span><br /><span style="color: rgb(0,0,0);">@ContextConfiguration(locations</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(42,0,255);">"/applicationContext.xml"</span> <span style="color: rgb(0,0,0);">})</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">MyJobTest</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="color: rgb(0,0,0);">@Autowired</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">SpringBeanJobFactory</span> <span style="color: rgb(0,0,0);">jobFactory;</span><br /><br /> <span style="color: rgb(0,0,0);">@Autowired</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">SchedulerFactoryBean</span> <span style="color: rgb(0,0,0);">schedulerFactory;</span><br /><br /> <span style="color: rgb(0,0,0);">@Autowired</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="color: rgb(0,0,0);">CronTriggerBean</span> <span style="color: rgb(0,0,0);">trigger;</span><br /><br /> <span style="color: rgb(0,0,0);">@Test</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">theJobPrintsToStandardOut()</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">TriggerFiredBundle</span> <span style="color: rgb(0,0,0);">bundle</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">TriggerFiredBundle(trigger.getJobDetail(),</span> <span style="color: rgb(0,0,0);">trigger,</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">CronCalendar(trigger.getCronExpression()),</span> <span style="font-weight: bold; color: rgb(127,0,85);">false</span><span style="color: rgb(0,0,0);">,</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Date(),</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Date(),</span> <span style="color: rgb(0,0,0);">trigger</span><br /> <span style="color: rgb(0,0,0);">.getPreviousFireTime(),</span> <span style="color: rgb(0,0,0);">trigger.getNextFireTime());</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Job</span> <span style="color: rgb(0,0,0);">job</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">jobFactory.newJob(bundle);</span><br /> <span style="color: rgb(0,0,0);">job.execute(</span><span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">JobExecutionContext(schedulerFactory.getScheduler(),</span> <span style="color: rgb(0,0,0);">bundle,</span> <span style="color: rgb(0,0,0);">job));</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br /><h4>Create an Assembly</h4><br />Now that we have a batch process, a test suite and a runner, we can create a distribution. Thanks to <a href="http://www.jroller.com/oburn/entry/using_maven2_to_generate_an">a comment by Valerio Schiavoni</a>, creating an executable jar with all its dependencies is easy in Maven2. We can add an incantation to our <em>pom.xml</em> that configures the jar to execute our <em>Main.java</em>:<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"> ....<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span>maven-assembly-plugin<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">artifactId</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">descriptorRefs</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">descriptorRef</span><span style="color: rgb(0,128,128);">></span>jar-with-dependencies<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">descriptorRef</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">descriptorRefs</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">archive</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">manifest</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">mainClass</span><span style="color: rgb(0,128,128);">></span>timezra.blog.spring_batch.Main<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">mainClass</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">manifest</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">archive</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">configuration</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugin</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">plugins</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">build</span><span style="color: rgb(0,128,128);">></span><br /> ....</span><br /></div><br />We will assemble this distribution by invoking Run As -> Maven assembly:assembly from inside Eclipse.<br />We can run the jar from the command-line by invoking <em>java -jar timezra.blog.spring_batch-0.0.1-SNAPSHOT-jar-with-dependencies.jar</em>.<br /><br />We now have a robust infrastructure for easily adding new jobs to our runner, for testing those jobs, and for creating an executable distribution.<br /><img src="http://farm4.static.flickr.com/3626/3320110523_c89a4dfb46_o.png" alt="The final project setup." />Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com16tag:blogger.com,1999:blog-106449775438946661.post-49110596012182797882009-02-18T17:07:00.000-08:002009-05-29T09:40:40.056-07:00STIQ, Eclipse, Ant and Hudson<h4>Goal:</h4><br />By the end of this entry, the user will have the tools for running a StoryTestIQ project from Eclipse and will be able to automate the test runs, either serially or in parallel, from a Continuous Integration server such as Hudson.<br /><br /><h4>Prepare STIQ</h4><br />First, we will need to download the <a href="http://sourceforge.net/project/showfiles.php?group_id=166747">STIQ binary</a>. The latest version, as of this entry, is 2.0 RC5.<br />From the extracted distribution, delete all the <em>/*.bat</em> files. For this example, we will be running STIQ from inside Eclipse and from Ant. We can also delete the following unused files and directories: <em>/repository/FrameworkTests</em>, <em>/repository/ProjectRoot/IntegrationTests/SmokeTests</em>, <em>/repository/ProjectRoot/SprintTests/SprintOne</em> (the existing test suite is buggy and needs to be re-created), <em>/bin/lib/jdbc-csv-mock.jar</em>, <em>/bin/lib/junit-3.8.1.jar</em>, <em>/bin/lib/ojdbc-14.jar</em>, <em>/bin/lib/sqlserver-1.0.809.jar</em>. <br />If you need to use a specific database driver for your tests, then add it to <em>/bin/lib</em>, and configure it in <em>storytestiq.properties</em>.<br />For this example, we will add <a href="http://jquery.com/">the latest jquery production download</a> to <em>/repository/extensions/display</em> as well. As of this writing, the latest production distribution is <em>jquery-1.3.1.min.js</em>.<br /> <br /><h4>STIQ in Eclipse</h4><br />To run STIQ from inside Eclipse, we can create a new plug-in project. For this example, the project is named <em>timezra.blog.stiq</em>. Because STIQ distributes its library files in <em>/bin</em> and <em>/bin/lib</em>, we will make sure to use <em>build</em> instead of <em>bin</em> for the compilation output folder.<br />In the plug-in MANIFEST.MF, we will also need to specify these dependencies: <em>org.eclipse.core.runtime</em>, <em>org.eclipse.swt</em> and <em>org.eclipse.jface</em>.<br />We can then copy the prepared STIQ distribution directly into the root of the project.<br /><br />We will then add the required STIQ libraries to the classpath of the MANIFEST.MF: <em>/bin/storytestiq.jar</em>, <em>/bin/lib/fitlibrary-1.1.jar</em>, <em>/bin/lib/selenium-server.jar</em>, <em>/bin/lib/Tidy.jar</em>.<br />Finally, in order to run STIQ as a Java application from inside Eclipse, we can create a <em>Main.java</em>:<br /><div style="overflow:auto;width:100%;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="font-weight: bold; color: rgb(127,0,85);">package</span> <span style="color: rgb(0,0,0);">timezra.blog.stiq;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.io.FileInputStream;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.io.IOException;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Properties;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">java.util.Map.Entry;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.jface.layout.GridDataFactory;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.jface.layout.GridLayoutFactory;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.swt.SWT;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.swt.browser.Browser;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.swt.widgets.Display;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">org.eclipse.swt.widgets.Shell;</span><br /><span style="font-weight: bold; color: rgb(127,0,85);">import</span> <span style="color: rgb(0,0,0);">fitnesse.FitNesse;</span><br /><br /><span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">class</span> <span style="color: rgb(0,0,0);">Main</span> <span style="color: rgb(0,0,0);">{</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">public</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">main(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String[]</span> <span style="color: rgb(0,0,0);">args)</span> <span style="font-weight: bold; color: rgb(127,0,85);">throws</span> <span style="color: rgb(0,0,0);">Exception</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">loadProperties(</span><span style="color: rgb(42,0,255);">"storytestiq.properties"</span><span style="color: rgb(0,0,0);">);</span><br /><br /> <span style="color: rgb(0,0,0);">FitNesse</span> <span style="color: rgb(0,0,0);">fitnesse</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">;</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">try</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">fitnesse</span> <span style="color: rgb(0,0,0);">=</span> <span style="color: rgb(0,0,0);">FitNesse.startFitNesse(</span><span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">String[]</span> <span style="color: rgb(0,0,0);">{</span> <span style="color: rgb(42,0,255);">"-o"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">"-p"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">"9999"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">"-r"</span><span style="color: rgb(0,0,0);">,</span> <span style="color: rgb(42,0,255);">"repository"</span> <span style="color: rgb(0,0,0);">});</span><br /> <span style="color: rgb(0,0,0);">startBrowser();</span><br /> <span style="color: rgb(0,0,0);">}</span> <span style="font-weight: bold; color: rgb(127,0,85);">finally</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(fitnesse</span> <span style="color: rgb(0,0,0);">!=</span> <span style="font-weight: bold; color: rgb(127,0,85);">null</span><span style="color: rgb(0,0,0);">)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">fitnesse.stop();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">loadProperties(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">String</span> <span style="color: rgb(0,0,0);">fileName)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Properties</span> <span style="color: rgb(0,0,0);">properties</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Properties();</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">try</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">properties.load(</span><span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">FileInputStream(fileName));</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">for</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Entry<Object,</span> <span style="color: rgb(0,0,0);">Object></span> <span style="color: rgb(0,0,0);">entry</span> <span style="color: rgb(0,0,0);">:</span> <span style="color: rgb(0,0,0);">properties.entrySet())</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">System.setProperty((String)</span> <span style="color: rgb(0,0,0);">entry.getKey(),</span> <span style="color: rgb(0,0,0);">(String)</span> <span style="color: rgb(0,0,0);">entry.getValue());</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span> <span style="font-weight: bold; color: rgb(127,0,85);">catch</span> <span style="color: rgb(0,0,0);">(</span><span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">IOException</span> <span style="color: rgb(0,0,0);">e)</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="color: rgb(0,0,0);">e.printStackTrace();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><br /> <span style="font-weight: bold; color: rgb(127,0,85);">private</span> <span style="font-weight: bold; color: rgb(127,0,85);">static</span> <span style="font-weight: bold; color: rgb(127,0,85);">void</span> <span style="color: rgb(0,0,0);">startBrowser()</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Display</span> <span style="color: rgb(0,0,0);">display</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Display();</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Shell</span> <span style="color: rgb(0,0,0);">shell</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Shell(display);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">final</span> <span style="color: rgb(0,0,0);">Browser</span> <span style="color: rgb(0,0,0);">browser</span> <span style="color: rgb(0,0,0);">=</span> <span style="font-weight: bold; color: rgb(127,0,85);">new</span> <span style="color: rgb(0,0,0);">Browser(shell,</span> <span style="color: rgb(0,0,0);">SWT.NONE);</span><br /> <span style="color: rgb(0,0,0);">GridDataFactory.fillDefaults().span(3,</span> <span style="color: rgb(0,0,0);">1).grab(</span><span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">,</span> <span style="font-weight: bold; color: rgb(127,0,85);">true</span><span style="color: rgb(0,0,0);">).applyTo(browser);</span><br /> <span style="color: rgb(0,0,0);">GridLayoutFactory.fillDefaults().numColumns(3).generateLayout(shell);</span><br /> <span style="color: rgb(0,0,0);">shell.open();</span><br /> <span style="color: rgb(0,0,0);">browser.setUrl(</span><span style="color: rgb(42,0,255);">"http://localhost:9999/stiq/runner.hta?startPage=/ProjectRoot"</span><span style="color: rgb(0,0,0);">);</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">while</span> <span style="color: rgb(0,0,0);">(!shell.isDisposed())</span> <span style="color: rgb(0,0,0);">{</span><br /> <span style="font-weight: bold; color: rgb(127,0,85);">if</span> <span style="color: rgb(0,0,0);">(!display.readAndDispatch())</span><br /> <span style="color: rgb(0,0,0);">display.sleep();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /> <span style="color: rgb(0,0,0);">display.dispose();</span><br /> <span style="color: rgb(0,0,0);">}</span><br /><span style="color: rgb(0,0,0);">}</span><br /></span><br /></div><br /><br />We can begin building acceptance tests by running <em>Main.java</em> as a Java application. For this example, I have setup two sets of SprintTests, all tagged as <em>integration</em>.<br /><br /><img src="http://farm4.static.flickr.com/3357/3291853262_cc3cca8f4e_o.png" alt="The STIQ project in Eclipse." /><br />Your STIQ project in Eclipse should look similar.<br /><br /><h4>STIQ and Ant</h4><br />To run the the example STIQ tests from Ant, we can replace the existing <em>/runner.xml</em> with another version that uses better formatting and has options for running all integration tests serially or SprintTests in parallel.<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,0,128);"><project</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"STIQ-Runner"</span> <span style="color: rgb(0,0,128);">default=</span><span style="color: rgb(0,128,0);">"usage"</span><span style="color: rgb(0,0,128);">></span><br /><br /> <span style="color: rgb(0,0,128);"><description></span><span style="color: rgb(0,0,0);">StoryTestIQ</span> <span style="color: rgb(0,0,0);">(STIQ)</span> <span style="color: rgb(0,0,0);">is</span> <span style="color: rgb(0,0,0);">a</span> <span style="color: rgb(0,0,0);">mashup</span> <span style="color: rgb(0,0,0);">of</span> <span style="color: rgb(0,0,0);">Selenium</span> <span style="color: rgb(0,0,0);">and</span> <span style="color: rgb(0,0,0);">FitNesse.</span> <span style="color: rgb(0,0,0);">This</span> <span style="color: rgb(0,0,0);">file</span> <span style="color: rgb(0,0,0);">is</span> <span style="color: rgb(0,0,0);">the</span> <span style="color: rgb(0,0,0);">STIQ</span> <span style="color: rgb(0,0,0);">runner.</span><span style="color: rgb(0,0,128);"></description></span><br /><br /> <span style="color: rgb(0,0,128);"><dirname</span> <span style="color: rgb(0,0,128);">file=</span><span style="color: rgb(0,128,0);">"${ant.file.STIQ-Runner}"</span> <span style="color: rgb(0,0,128);">property=</span><span style="color: rgb(0,128,0);">"install.dir"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><property</span> <span style="color: rgb(0,0,128);">file=</span><span style="color: rgb(0,128,0);">"${install.dir}/storytestiq.properties"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><property</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"stiq-results"</span> <span style="color: rgb(0,0,128);">location=</span><span style="color: rgb(0,128,0);">"${install.dir}/stiq-results"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><property</span> <span style="color: rgb(0,0,128);">environment=</span><span style="color: rgb(0,128,0);">"env"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><loadfile</span> <span style="color: rgb(0,0,128);">property=</span><span style="color: rgb(0,128,0);">"jquery"</span> <span style="color: rgb(0,0,128);">srcfile=</span><span style="color: rgb(0,128,0);">"${install.dir}/repository/extensions/display/jquery-1.3.1.min.js"</span> <span style="color: rgb(0,0,128);">/></span><br /><br /> <span style="color: rgb(0,0,128);"><path</span> <span style="color: rgb(0,0,128);">id=</span><span style="color: rgb(0,128,0);">"stiq-classpath"</span><span style="color: rgb(0,0,128);">></span><br /> <span style="color: rgb(0,0,128);"><fileset</span> <span style="color: rgb(0,0,128);">dir=</span><span style="color: rgb(0,128,0);">"${install.dir}/bin"</span><span style="color: rgb(0,0,128);">></span><br /> <span style="color: rgb(0,0,128);"><include</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"**/*.jar"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"></fileset></span><br /> <span style="color: rgb(0,0,128);"></path></span><br /><br /> <span style="color: rgb(0,0,128);"><target</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"usage"</span><span style="color: rgb(0,0,128);">></span><br /> <span style="color: rgb(0,0,128);"><echo</span> <span style="color: rgb(0,0,128);">level=</span><span style="color: rgb(0,128,0);">"info"</span><span style="color: rgb(0,0,128);">></span><br /> <span style="color: rgb(0,0,0);">clean:</span> <span style="color: rgb(0,0,0);">remove</span> <span style="color: rgb(0,0,0);">any</span> <span style="color: rgb(0,0,0);">test</span> <span style="color: rgb(0,0,0);">result</span> <span style="color: rgb(0,0,0);">artifacts</span><br /> <span style="color: rgb(0,0,0);">run-integration-tests:</span> <span style="color: rgb(0,0,0);">runs</span> <span style="color: rgb(0,0,0);">all</span> <span style="color: rgb(0,0,0);">STIQ</span> <span style="color: rgb(0,0,0);">IntegrationTests</span><br /> <span style="color: rgb(0,0,0);">run-sprint-tests:</span> <span style="color: rgb(0,0,0);">runs</span> <span style="color: rgb(0,0,0);">STIQ</span> <span style="color: rgb(0,0,0);">Sprint</span> <span style="color: rgb(0,0,0);">Tests</span> <span style="color: rgb(0,0,0);">in</span> <span style="color: rgb(0,0,0);">Parallel</span><br /> <span style="color: rgb(0,0,128);"></echo></span><br /> <span style="color: rgb(0,0,128);"></target></span><br /><br /> <span style="color: rgb(0,0,128);"><target</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"clean"</span><span style="color: rgb(0,0,128);">></span><br /> <span style="color: rgb(0,0,128);"><delete</span> <span style="color: rgb(0,0,128);">failonerror=</span><span style="color: rgb(0,128,0);">"false"</span> <span style="color: rgb(0,0,128);">includeemptydirs=</span><span style="color: rgb(0,128,0);">"true"</span><span style="color: rgb(0,0,128);">></span><br /> <span style="color: rgb(0,0,128);"><fileset</span> <span style="color: rgb(0,0,128);">dir=</span><span style="color: rgb(0,128,0);">"${stiq-results}"</span><span style="color: rgb(0,0,128);">></span><br /> <span style="color: rgb(0,0,128);"><include</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"*/**"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"></fileset></span><br /> <span style="color: rgb(0,0,128);"></delete></span><br /> <span style="color: rgb(0,0,128);"></target></span><br /><br /> <span style="color: rgb(0,0,128);"><target</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"init"</span><span style="color: rgb(0,0,128);">></span><br /> <span style="color: rgb(0,0,128);"><tstamp></span><br /> <span style="color: rgb(0,0,128);"><format</span> <span style="color: rgb(0,0,128);">property=</span><span style="color: rgb(0,128,0);">"today"</span> <span style="color: rgb(0,0,128);">pattern=</span><span style="color: rgb(0,128,0);">"MMMM d yyyy hh:mm a"</span> <span style="color: rgb(0,0,128);">locale=</span><span style="color: rgb(0,128,0);">"en,US"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"></tstamp></span><br /> <span style="color: rgb(0,0,128);"></target></span><br /><br /> <span style="color: rgb(0,0,128);"><target</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"run-integration-tests"</span> <span style="color: rgb(0,0,128);">depends=</span><span style="color: rgb(0,128,0);">"clean, init"</span><span style="color: rgb(0,0,128);">></span><br /> <span style="color: rgb(0,0,128);"><run-stiq-suite</span> <span style="color: rgb(0,0,128);">start-page=</span><span style="color: rgb(0,128,0);">"/.ProjectRoot"</span> <span style="color: rgb(0,0,128);">suite-page=</span><span style="color: rgb(0,128,0);">"IntegrationTests"</span> <span style="color: rgb(0,0,128);">output-dir=</span><span style="color: rgb(0,128,0);">"${stiq-results}"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><publish-results-as-html</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><fail></span><br /> <span style="color: rgb(0,0,128);"><condition></span><br /> <span style="color: rgb(0,0,128);"><not></span><br /> <span style="color: rgb(0,0,128);"><equals</span> <span style="color: rgb(0,0,128);">arg1=</span><span style="color: rgb(0,128,0);">"${stiq-suite-result}"</span> <span style="color: rgb(0,0,128);">arg2=</span><span style="color: rgb(0,128,0);">"0"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"></not></span><br /> <span style="color: rgb(0,0,128);"></condition></span><br /> <span style="color: rgb(0,0,128);"></fail></span><br /> <span style="color: rgb(0,0,128);"></target></span><br /><br /> <span style="color: rgb(0,0,128);"><target</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"run-sprint-tests"</span> <span style="color: rgb(0,0,128);">depends=</span><span style="color: rgb(0,128,0);">"clean, init"</span><span style="color: rgb(0,0,128);">></span><br /> <span style="color: rgb(0,0,128);"><parallel</span> <span style="color: rgb(0,0,128);">threadcount=</span><span style="color: rgb(0,128,0);">"2"</span> <span style="color: rgb(0,0,128);">></span><br /> <span style="color: rgb(0,0,128);"><run-stiq-suite</span> <span style="color: rgb(0,0,128);">start-page=</span><span style="color: rgb(0,128,0);">"/.ProjectRoot.SprintTests"</span> <span style="color: rgb(0,0,128);">suite-page=</span><span style="color: rgb(0,128,0);">"SprintOne"</span> <span style="color: rgb(0,0,128);">output-dir=</span><span style="color: rgb(0,128,0);">"${stiq-results}/SprintOne"</span> <span style="color: rgb(0,0,128);">port=</span><span style="color: rgb(0,128,0);">"9991"</span> <span style="color: rgb(0,0,128);">result-property=</span><span style="color: rgb(0,128,0);">"sprint.one.result"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><run-stiq-suite</span> <span style="color: rgb(0,0,128);">start-page=</span><span style="color: rgb(0,128,0);">"/.ProjectRoot.SprintTests"</span> <span style="color: rgb(0,0,128);">suite-page=</span><span style="color: rgb(0,128,0);">"SprintTwo"</span> <span style="color: rgb(0,0,128);">output-dir=</span><span style="color: rgb(0,128,0);">"${stiq-results}/SprintTwo"</span> <span style="color: rgb(0,0,128);">port=</span><span style="color: rgb(0,128,0);">"9992"</span> <span style="color: rgb(0,0,128);">result-property=</span><span style="color: rgb(0,128,0);">"sprint.two.result"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"></parallel></span><br /> <span style="color: rgb(0,0,128);"><concat</span> <span style="color: rgb(0,0,128);">append=</span><span style="color: rgb(0,128,0);">"true"</span> <span style="color: rgb(0,0,128);">destfile=</span><span style="color: rgb(0,128,0);">"${stiq-results}/stiq-results.xml"</span><span style="color: rgb(0,0,128);">></span><span style="color: rgb(0,0,0);">&lt;parallel&gt;</span><span style="color: rgb(0,0,128);"></concat></span><br /> <span style="color: rgb(0,0,128);"><concat</span> <span style="color: rgb(0,0,128);">append=</span><span style="color: rgb(0,128,0);">"true"</span> <span style="color: rgb(0,0,128);">destfile=</span><span style="color: rgb(0,128,0);">"${stiq-results}/stiq-results.xml"</span><span style="color: rgb(0,0,128);">></span><br /> <span style="color: rgb(0,0,128);"><fileset</span> <span style="color: rgb(0,0,128);">dir=</span><span style="color: rgb(0,128,0);">"${stiq-results}"</span><span style="color: rgb(0,0,128);">></span><br /> <span style="color: rgb(0,0,128);"><include</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"*/stiq-results.xml"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"></fileset></span><br /> <span style="color: rgb(0,0,128);"></concat></span><br /> <span style="color: rgb(0,0,128);"><concat</span> <span style="color: rgb(0,0,128);">append=</span><span style="color: rgb(0,128,0);">"true"</span> <span style="color: rgb(0,0,128);">destfile=</span><span style="color: rgb(0,128,0);">"${stiq-results}/stiq-results.xml"</span><span style="color: rgb(0,0,128);">></span><span style="color: rgb(0,0,0);">&lt;/parallel&gt;</span><span style="color: rgb(0,0,128);"></concat></span><br /> <span style="color: rgb(0,0,128);"><publish-results-as-html</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><fail></span><br /> <span style="color: rgb(0,0,128);"><condition></span><br /> <span style="color: rgb(0,0,128);"><not></span><br /> <span style="color: rgb(0,0,128);"><and></span><br /> <span style="color: rgb(0,0,128);"><equals</span> <span style="color: rgb(0,0,128);">arg1=</span><span style="color: rgb(0,128,0);">"${sprint.one.result}"</span> <span style="color: rgb(0,0,128);">arg2=</span><span style="color: rgb(0,128,0);">"0"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><equals</span> <span style="color: rgb(0,0,128);">arg1=</span><span style="color: rgb(0,128,0);">"${sprint.two.result}"</span> <span style="color: rgb(0,0,128);">arg2=</span><span style="color: rgb(0,128,0);">"0"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"></and></span><br /> <span style="color: rgb(0,0,128);"></not></span><br /> <span style="color: rgb(0,0,128);"></condition></span><br /> <span style="color: rgb(0,0,128);"></fail></span><br /> <span style="color: rgb(0,0,128);"></target></span><br /><br /> <span style="color: rgb(0,0,128);"><macrodef</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"run-stiq-suite"</span><span style="color: rgb(0,0,128);">></span><br /> <span style="color: rgb(0,0,128);"><attribute</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"output-dir"</span> <span style="color: rgb(0,0,128);">default=</span><span style="color: rgb(0,128,0);">"${install.dir}"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><attribute</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"port"</span> <span style="color: rgb(0,0,128);">default=</span><span style="color: rgb(0,128,0);">"9999"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><attribute</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"repository-path"</span> <span style="color: rgb(0,0,128);">default=</span><span style="color: rgb(0,128,0);">"repository"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><attribute</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"result-property"</span> <span style="color: rgb(0,0,128);">default=</span><span style="color: rgb(0,128,0);">"stiq-suite-result"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><attribute</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"start-page"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><attribute</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"suite-page"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><sequential></span><br /> <span style="color: rgb(0,0,128);"><mkdir</span> <span style="color: rgb(0,0,128);">dir=</span><span style="color: rgb(0,128,0);">"@{output-dir}"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><echo</span> <span style="color: rgb(0,0,128);">level=</span><span style="color: rgb(0,128,0);">"info"</span><span style="color: rgb(0,0,128);">></span><span style="color: rgb(0,0,0);">Executing</span> <span style="color: rgb(0,0,0);">suite</span> <span style="color: rgb(0,0,0);">[@{suite-page}]</span> <span style="color: rgb(0,0,0);">in</span> <span style="color: rgb(0,0,0);">STIQ.</span><span style="color: rgb(0,0,128);"></echo></span><br /> <span style="color: rgb(0,0,128);"><java</span> <span style="color: rgb(0,0,128);">classname=</span><span style="color: rgb(0,128,0);">"fitnesse.runner.FitnessRunner"</span> <span style="color: rgb(0,0,128);">classpathref=</span><span style="color: rgb(0,128,0);">"stiq-classpath"</span> <span style="color: rgb(0,0,128);">fork=</span><span style="color: rgb(0,128,0);">"true"</span> <span style="color: rgb(0,0,128);">resultproperty=</span><span style="color: rgb(0,128,0);">"@{result-property}"</span><span style="color: rgb(0,0,128);">></span><br /> <span style="color: rgb(0,0,128);"><sysproperty</span> <span style="color: rgb(0,0,128);">key=</span><span style="color: rgb(0,128,0);">"STIQDatabaseDriver"</span> <span style="color: rgb(0,0,128);">value=</span><span style="color: rgb(0,128,0);">"${STIQDatabaseDriver}"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><sysproperty</span> <span style="color: rgb(0,0,128);">key=</span><span style="color: rgb(0,128,0);">"STIQDatabaseConnectionString"</span> <span style="color: rgb(0,0,128);">value=</span><span style="color: rgb(0,128,0);">"${STIQDatabaseConnectionString}"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><sysproperty</span> <span style="color: rgb(0,0,128);">key=</span><span style="color: rgb(0,128,0);">"STIQDatabaseUsername"</span> <span style="color: rgb(0,0,128);">value=</span><span style="color: rgb(0,128,0);">"${STIQDatabaseUsername}"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><sysproperty</span> <span style="color: rgb(0,0,128);">key=</span><span style="color: rgb(0,128,0);">"STIQDatabasePassword"</span> <span style="color: rgb(0,0,128);">value=</span><span style="color: rgb(0,128,0);">"${STIQDatabasePassword}"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><arg</span> <span style="color: rgb(0,0,128);">line=</span><span style="color: rgb(0,128,0);">"@{port}"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><arg</span> <span style="color: rgb(0,0,128);">line=</span><span style="color: rgb(0,128,0);">"@{repository-path}"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><arg</span> <span style="color: rgb(0,0,128);">line=</span><span style="color: rgb(0,128,0);">"@{start-page}"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><arg</span> <span style="color: rgb(0,0,128);">line=</span><span style="color: rgb(0,128,0);">"@{suite-page}"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><arg</span> <span style="color: rgb(0,0,128);">line=</span><span style="color: rgb(0,128,0);">"@{output-dir}"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"></java></span><br /> <span style="color: rgb(0,0,128);"></sequential></span><br /> <span style="color: rgb(0,0,128);"></macrodef></span><br /><br /> <span style="color: rgb(0,0,128);"><macrodef</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"publish-results-as-html"</span><span style="color: rgb(0,0,128);">></span><br /> <span style="color: rgb(0,0,128);"><sequential></span><br /> <span style="color: rgb(0,0,128);"><xslt</span> <span style="color: rgb(0,0,128);">basedir=</span><span style="color: rgb(0,128,0);">"${stiq-results}"</span> <span style="color: rgb(0,0,128);">destdir=</span><span style="color: rgb(0,128,0);">"${stiq-results}"</span> <span style="color: rgb(0,0,128);">includes=</span><span style="color: rgb(0,128,0);">"stiq-results.xml"</span> <span style="color: rgb(0,0,128);">out=</span><span style="color: rgb(0,128,0);">"stiq-results.html"</span> <span style="color: rgb(0,0,128);">style=</span><span style="color: rgb(0,128,0);">"stiq.xsl"</span><span style="color: rgb(0,0,128);">></span><br /> <span style="color: rgb(0,0,128);"><param</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"applicationPath"</span> <span style="color: rgb(0,0,128);">expression=</span><span style="color: rgb(0,128,0);">"${install.dir}"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><param</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"buildDate"</span> <span style="color: rgb(0,0,128);">expression=</span><span style="color: rgb(0,128,0);">"${today}"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><param</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"buildNumber"</span> <span style="color: rgb(0,0,128);">expression=</span><span style="color: rgb(0,128,0);">"${env.BUILD_NUMBER}"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"><param</span> <span style="color: rgb(0,0,128);">name=</span><span style="color: rgb(0,128,0);">"jquery"</span> <span style="color: rgb(0,0,128);">expression=</span><span style="color: rgb(0,128,0);">"${jquery}"</span> <span style="color: rgb(0,0,128);">/></span><br /> <span style="color: rgb(0,0,128);"></xslt></span><br /> <span style="color: rgb(0,0,128);"></sequential></span><br /> <span style="color: rgb(0,0,128);"></macrodef></span><br /><span style="color: rgb(0,0,128);"></project></span><br /></span><br /></div><br /><br /><b>NB:</b> if you are using a version of jQuery other than <em>jquery-1.3.1.min.js</em>, this version can be configured among the Ant properties.<br /><br />There are two STIQ targets in the Ant script: <em>run-integration-tests</em> will run all STIQ tests tagged as <em>integration</em>; <em>run-sprint-tests</em> will run each of the SprintTest suites in parallel. Note that, when using the latter target, if we add more SprintTest suites, we will also need to add new parallel macro calls to <em>run-stiq-suite</em> as well as failure condition checks, and we may want to increase the parallel threadcount.<br /><br />Note also that the <em>publish-results-as-html</em> macro expects a <em>/stiq.xsl</em> stylesheet for performing the transform between stiq.xml test output and human-readable HTML. This stylesheet, originally written by Kendrick Burson, transforms the output from either an integration or parallel STIQ run into an HTML report.<br /><div style="overflow:auto;width:100%;height:500px;padding:5px;background-color:white;border-style:dashed;border-width:1px"><br /><span style="font-family: courier new; font-size: 10pt;"><span style="color: rgb(0,128,128);"><?</span><span style="color: rgb(63,127,127);">xml</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span><span style="color: rgb(0,128,128);">?></span><br /><span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:stylesheet</span> <span style="color: rgb(127,0,127);">version</span>=<span style="font-style: italic; color: rgb(42,0,255);">"1.0"</span><br /> <span style="color: rgb(127,0,127);">xmlns:xsl</span>=<span style="font-style: italic; color: rgb(42,0,255);">"http://www.w3.org/1999/XSL/Transform"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:output</span> <span style="color: rgb(127,0,127);">method</span>=<span style="font-style: italic; color: rgb(42,0,255);">"html"</span> <span style="color: rgb(127,0,127);">indent</span>=<span style="font-style: italic; color: rgb(42,0,255);">"yes"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:param</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"applicationPath"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:param</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"buildDate"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:param</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"jquery"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:param</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"buildNumber"</span> <span style="color: rgb(127,0,127);">select</span>=<span style="font-style: italic; color: rgb(42,0,255);">""</span> <span style="color: rgb(0,128,128);">/></span><br /><br /> <span style="color: rgb(63,95,191);"><!--</span><span style="color: rgb(63,95,191);"> ############################################################# </span><span style="color: rgb(63,95,191);">--></span><br /> <span style="color: rgb(63,95,191);"><!--</span><span style="color: rgb(63,95,191);"> Template: match / </span><span style="color: rgb(63,95,191);">--></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:template</span> <span style="color: rgb(127,0,127);">match</span>=<span style="font-style: italic; color: rgb(42,0,255);">"/"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">html</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">head</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">title</span><span style="color: rgb(0,128,128);">></span>STIQ Test Results<span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">title</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">link</span> <span style="color: rgb(127,0,127);">rel</span>=<span style="font-style: italic; color: rgb(42,0,255);">"stylesheet"</span> <span style="color: rgb(127,0,127);">type</span>=<span style="font-style: italic; color: rgb(42,0,255);">"text/css"</span> <span style="color: rgb(127,0,127);">media</span>=<span style="font-style: italic; color: rgb(42,0,255);">"screen"</span><br /> <span style="color: rgb(127,0,127);">href</span>=<span style="font-style: italic; color: rgb(42,0,255);">"file://{$applicationPath}/repository/extensions/display/selenium-test.css"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:call-template</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"writeClientScript"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">head</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">body</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">table</span> <span style="color: rgb(127,0,127);">border</span>=<span style="font-style: italic; color: rgb(42,0,255);">"0"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">tr</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">td</span><span style="color: rgb(0,128,128);">></span><br /> Hudson Build #<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:value-of</span> <span style="color: rgb(127,0,127);">select</span>=<span style="font-style: italic; color: rgb(42,0,255);">"$buildNumber"</span> <span style="color: rgb(0,128,128);">/></span><br /> completed on<br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:value-of</span> <span style="color: rgb(127,0,127);">select</span>=<span style="font-style: italic; color: rgb(42,0,255);">"$buildDate"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">td</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">tr</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">table</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">br</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:apply-templates</span> <span style="color: rgb(127,0,127);">select</span>=<span style="font-style: italic; color: rgb(42,0,255);">"parallel"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:apply-templates</span> <span style="color: rgb(127,0,127);">select</span>=<span style="font-style: italic; color: rgb(42,0,255);">"stiq"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">body</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">html</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">xsl:template</span><span style="color: rgb(0,128,128);">></span><br /><br /> <span style="color: rgb(63,95,191);"><!--</span><span style="color: rgb(63,95,191);"> ############################################################# </span><span style="color: rgb(63,95,191);">--></span><br /> <span style="color: rgb(63,95,191);"><!--</span><span style="color: rgb(63,95,191);"> Template: match <parallel> </span><span style="color: rgb(63,95,191);">--></span><br /> <span style="color: rgb(0,128,128);"><</span>xsl:template match="parallel"><br /> <table border="0"><br /> <tr><br /> <td align="left"><br /> <b><br /> <xsl:text>STIQ Tests total: </xsl:text><br /> <xsl:value-of select="count(stiq/body/table/tbody/tr[td/a])" /><br /> <xsl:text>&#160;&#160;&#160;(</xsl:text><br /> <font color="green"><br /> <xsl:text>Passed: </xsl:text><xsl:value-of select = "count(stiq/body/table/tbody/tr[td/a and @class=' status_passed'])" /><br /> </font><br /> <xsl:text>&#160;&#160;&#160;</xsl:text><br /> <font color="red"><br /> <xsl:text>Failed: </xsl:text><xsl:value-of select = "count(stiq/body/table/tbody/tr[td/a and @class=' status_failed'])" /><br /> </font><br /> <xsl:text>)</xsl:text><br /> </b><br /> </td><br /> </tr><br /> </table><br /> <br/><br /> <xsl:apply-templates select="stiq" /><br /> </xsl:template><br /><br /> <!-- ############################################################# --><br /> <!-- Template: match <stiq> --><br /> <xsl:template match="stiq"><br /> <table class="suiteheader"><br /> <tr><br /> <td align="left"><br /> <b><br /> <xsl:text>Suite Tests total: </xsl:text><br /> <xsl:value-of select="count(body/table/tbody/tr[td/a])" /><br /> <xsl:text>&#160;&#160;&#160;(</xsl:text><br /> <font color="green"><br /> <xsl:text>Passed: </xsl:text><xsl:value-of select = "count(body/table/tbody/tr[td/a and @class=' status_passed'])" /><br /> </font><br /> <xsl:text>&#160;&#160;&#160;</xsl:text><br /> <font color="red"><br /> <xsl:text>Failed: </xsl:text><xsl:value-of select = "count(body/table/tbody/tr[td/a and @class=' status_failed'])" /><br /> </font><br /> <xsl:text>)</xsl:text><br /> </b><br /> </td><br /> </tr><br /> </table><br /> <table class="yo"><br /> <xsl:apply-templates select="body/table/tbody/tr" mode="r1"><br /> <xsl:sort select="td[1]/a" /><br /> </xsl:apply-templates><br /> </table><br /> <br/><br /> </xsl:template><br /><br /> <!-- ############################################################# --><br /> <!-- Template: match <tr> --><br /> <xsl:template match="tr" mode="r1"><br /> <xsl:element name="tr"><br /> <xsl:attribute name="class"><br /> <xsl:value-of select="@class"/><br /> </xsl:attribute><br /> <br /> <xsl:choose><br /> <!-- First Row - Test Suite --><br /> <xsl:when test="position() = 1"><br /> <!-- First Column - Row Number - blank for test suite name --><br /> <td valign="top">&#160;</td><br /> <!-- Second Column - Test Name --><br /> <td valign="top" colspan="2"><br /> <xsl:copy-of select="td[1]/*" /><br /> </td><br /> </xsl:when><br /> <br /> <!-- Test Results --> <br /> <xsl:otherwise><br /> <!-- First Column - Row Number --><br /> <td valign="top" class="{./@class}"><xsl:value-of select="position() - 1"/></td><br /> <br /> <!-- Second Column - Test Name + test results in hidden div --><br /> <td valign="top" class="{./@class}"><br /> <br /> <!-- clickable link to show test results using test name as title --><br /> <a href="javascript:void(0);" onclick="javascript:$('#{generate-id(td[2])}').slideToggle();" title="{td[1]/a/@href}"><br /> <xsl:value-of select="td[1]/a" /><br /> </a><br /> <br /> <!-- Hidden div show results of test. --><br /> <div id="{generate-id(td[2])}" valign="top" style="display:none" class="{./@class}" ><br /> <blockquote> <br /> <xsl:apply-templates select="td[2]/*" mode="copy" /><br /> </blockquote><br /> </div><br /> </td><br /> </xsl:otherwise><br /> </xsl:choose><br /> </xsl:element><br /> </xsl:template><br /><br /> <!-- ############################################################# --><br /> <!-- Template: copy all nodes and attributes --><br /> <xsl:template match="@*|node()" mode="copy"><br /> <xsl:choose><br /> <!-- Hide stiq controls from report == we do not want viewers to accidentally click active links to stiq runtime env --><br /> <xsl:when test="local-name() = 'div' and ./@class='actions'"><br /> <xsl:comment>Remove STIQ Controls from report</xsl:comment><br /> </xsl:when><br /><br /> <!-- create collapsible sub table for included 'components' --><br /> <xsl:when test="local-name() = 'div' and ./@class='included'"><br /> <div class="stiqincluded"><br /> <span><br /> <xsl:if test="./div/table/tbody/tr/@class = ' status_failed'"><br /> <xsl:attribute name="style">background-color:#FF9999</xsl:attribute><br /> </xsl:if><br /> <span class="{./span/@class}"><br /> <xsl:text>Included page: </xsl:text><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">a</span> <span style="color: rgb(127,0,127);">href</span>=<span style="font-style: italic; color: rgb(42,0,255);">"javascript:void(0);"</span> <span style="color: rgb(127,0,127);">onclick</span>=<span style="font-style: italic; color: rgb(42,0,255);">"javascript:$('#{./div[@class='collapsable']/@id}').slideToggle();"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:value-of</span> <span style="color: rgb(127,0,127);">select</span>=<span style="font-style: italic; color: rgb(42,0,255);">"./span/a"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">a</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">span</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">span</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">br</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:apply-templates</span> <span style="color: rgb(127,0,127);">select</span>=<span style="font-style: italic; color: rgb(42,0,255);">"./div"</span> <span style="color: rgb(127,0,127);">mode</span>=<span style="font-style: italic; color: rgb(42,0,255);">"copy"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">div</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">xsl:when</span><span style="color: rgb(0,128,128);">></span><br /> <br /> <span style="color: rgb(63,95,191);"><!--</span><span style="color: rgb(63,95,191);"> Show table of values </span><span style="color: rgb(63,95,191);">--></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:when</span> <span style="color: rgb(127,0,127);">test</span>=<span style="font-style: italic; color: rgb(42,0,255);">"local-name() = 'table'"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">table</span> <span style="color: rgb(127,0,127);">class</span>=<span style="font-style: italic; color: rgb(42,0,255);">"stiqtest"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:apply-templates</span> <span style="color: rgb(127,0,127);">select</span>=<span style="font-style: italic; color: rgb(42,0,255);">"./*"</span> <span style="color: rgb(127,0,127);">mode</span>=<span style="font-style: italic; color: rgb(42,0,255);">"copy"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">table</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">xsl:when</span><span style="color: rgb(0,128,128);">></span><br /> <br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:when</span> <span style="color: rgb(127,0,127);">test</span>=<span style="font-style: italic; color: rgb(42,0,255);">"local-name() = 'a'"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">span</span> <span style="color: rgb(127,0,127);">style</span>=<span style="font-style: italic; color: rgb(42,0,255);">"color:blue"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:value-of</span> <span style="color: rgb(127,0,127);">select</span>=<span style="font-style: italic; color: rgb(42,0,255);">"."</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">span</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">xsl:when</span><span style="color: rgb(0,128,128);">></span><br /> <br /> <span style="color: rgb(63,95,191);"><!--</span><span style="color: rgb(63,95,191);"> Huh? Don't know what it is so just copy it </span><span style="color: rgb(63,95,191);">--></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:otherwise</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:copy</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:apply-templates</span> <span style="color: rgb(127,0,127);">select</span>=<span style="font-style: italic; color: rgb(42,0,255);">"@*|node()"</span> <span style="color: rgb(127,0,127);">mode</span>=<span style="font-style: italic; color: rgb(42,0,255);">"copy"</span><span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">xsl:copy</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">xsl:otherwise</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">xsl:choose</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">xsl:template</span><span style="color: rgb(0,128,128);">></span><br /> <br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:template</span> <span style="color: rgb(127,0,127);">name</span>=<span style="font-style: italic; color: rgb(42,0,255);">"writeClientScript"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">style</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><![CDATA[</span><span style="color: rgb(0,0,0);"> <br /> <!--<br /> div.stiqincluded<br /> {<br /> background: #F9F9F9;<br /> margin: 5px 0px 5px 0px;<br /> padding: 2px 2px 2px 2px;<br /> border: 1px dotted #909090;<br /> }<br /> div.collapsable<br /> {<br /> display: none;<br /> }<br /> table.suiteheader<br /> {<br /> margin: 2px;<br /> padding: 2px;<br /> border: solid #AAAAAA;<br /> border-width: 1px 1px 0px 1px;<br /> }<br /> table.stiqtest<br /> {<br /> background: #EEEEEE;<br /> margin: 2px;<br /> padding: 2px;<br /> border: solid #AAAAAA;<br /> border-width: 1px 1px 1px 1px;<br /> font-family: trebuchet ms, verdana, tahoma, arial, sans-serif;<br /> font-size: 1em;<br /> }<br /> .status_done {<br /> background-color: #EEFFEE;<br /> }<br /> .status_passed {<br /> background-color: #CCFFCC !important;<br /> }<br /> .status_failed {<br /> background-color: #FFCCCC;<br /> }<br /> --><br /> </span><span style="color: rgb(0,128,128);">]]></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">style</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">script</span> <span style="color: rgb(127,0,127);">LANGUAGE</span>=<span style="font-style: italic; color: rgb(42,0,255);">"javascript"</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"><</span><span style="color: rgb(63,127,127);">xsl:value-of</span> <span style="color: rgb(127,0,127);">select</span>=<span style="font-style: italic; color: rgb(42,0,255);">"$jquery"</span> <span style="color: rgb(0,128,128);">/></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">script</span><span style="color: rgb(0,128,128);">></span><br /> <span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">xsl:template</span><span style="color: rgb(0,128,128);">></span> <br /><span style="color: rgb(0,128,128);"></</span><span style="color: rgb(63,127,127);">xsl:stylesheet</span><span style="color: rgb(0,128,128);">></span></span><br /></div><br /><br /><h4>STIQ and Hudson</h4><br />For this example, we can setup <a href="http://tomcat.apache.org/index.html">Apache Tomcat</a> as a Windows service to run <a href="https://hudson.dev.java.net/">Hudson</a>.<br />We will want to ensure that Tomcat is setup to "Allow service to interact with desktop" so that we can view the automated STIQ test run.<br /><img src="http://farm4.static.flickr.com/3355/3291853278_280d0ba4cc_o.png" alt="The Tomcat Service configuration." /><br />The Windows Service setup for the instance of Tomcat running Hudson should look similar.<br /><br />From Hudson, we can build a freestyle software project to launch our STIQ tests with a custom workspace (i.e., the path to the Eclipse STIQ project workspace). We can then add a build task to <em>run-sprint-tests</em> with the custom <em>runner.xml</em>, and we can archive the <em>stiq-results/stiq-results.html</em> artifact.<br /><br /><img src="http://farm4.static.flickr.com/3579/3291035709_5f13c693e8_o.png" alt="The Hudson STIQ project configuration." /><br />The Hudson configuration for your STIQ project should look similar.<br /><br />We now have a standard setup for an Eclipse STIQ project, a way to launch STIQ from inside Eclipse, a way to run STIQ tests serially or in parallel from Ant, and a way to automate STIQ test runs from Hudson.Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com0tag:blogger.com,1999:blog-106449775438946661.post-26441755434316686992008-12-31T21:38:00.000-08:002008-12-31T22:01:21.803-08:00JFace AWT Selection Binding<h4>Goal</h4><br />The goal of this entry is to embed an AWT and Swing component in an Eclipse Editor and to bind the AWT selection change events to the Eclipse Selection Service.<br /><br /><h4>Create a Swing Tree and Tree Model</h4><br />Because we will be combining AWT components with an Eclipse Editor, we should first create a Plug-in project that will contribute to the UI. For this example, the project can be named <em>timezra.blog.swt_awt_selection_binding</em>.<br />For the Swing components, we will use the <a href="http://java.sun.com/docs/books/tutorial/uiswing/examples/components/TreeDemoProject/src/components/TreeDemo.java">example</a> from the <a href="http://java.sun.com/docs/books/tutorial/uiswing/components/tree.html">Sun Tree Tutorial</a> as a basis for our JTree and TreeModel.<br /><br />The Model Object<br /><div style="overflow:auto;width:60%;padding-bottom:5px"><br /><pre><br />package timezra.blog.swt_awt_selection_binding.awt;<br /><br />public class BookInfo {<br /> public final String bookName;<br /> public final String bookURL;<br /><br /> public BookInfo(final String bookName, final String bookURL) {<br /> this.bookName = bookName;<br /> this.bookURL = bookURL;<br /> }<br /><br /> @Override<br /> public String toString() {<br /> return bookName;<br /> }<br />}<br /></pre><br /></div><br /><br />We can use a factory method to build the JTree and populate the backing TreeModel.<br /><div style="overflow:auto;width:60%;padding-bottom:5px"><br /><pre><br />package timezra.blog.swt_awt_selection_binding.awt;<br /><br />import javax.swing.JTree;<br />import javax.swing.tree.DefaultMutableTreeNode;<br />import javax.swing.tree.DefaultTreeModel;<br /><br />public final class JTreeFactory {<br /> private JTreeFactory() {<br /> // singleton<br /> };<br /><br /> public static JTree create() {<br /> final DefaultMutableTreeNode top = new DefaultMutableTreeNode(<br /> "The Java Series");<br /> final DefaultMutableTreeNode category = new DefaultMutableTreeNode(<br /> "Books for Java Programmers");<br /> top.add(category);<br /> category.add(new DefaultMutableTreeNode(new BookInfo(<br /> "The Java Tutorial: A Short Course on the Basics",<br /> "tutorial.html")));<br /> category.add(new DefaultMutableTreeNode(new BookInfo(<br /> "The Java Tutorial Continued: The Rest of the JDK",<br /> "tutorialcont.html")));<br /> category.add(new DefaultMutableTreeNode(new BookInfo(<br /> "The JFC Swing Tutorial: A Guide to Constructing GUIs",<br /> "swingtutorial.html")));<br /> category.add(new DefaultMutableTreeNode(new BookInfo(<br /> "Effective Java Programming Language Guide", "bloch.html")));<br /> category.add(new DefaultMutableTreeNode(new BookInfo(<br /> "The Java Programming Language", "arnold.html")));<br /> category.add(new DefaultMutableTreeNode(new BookInfo(<br /> "The Java Developers Almanac", "chan.html")));<br /> return new JTree(new DefaultTreeModel(top));<br /> }<br />}<br /></pre><br /></div><br /><br /><h4>Create an Eclipse Editor</h4><br />We can create a very basic Eclipse Editor and contribute it through the plugin.xml. Here, the editor is opened for any file with the <em>.book</em> extension.<br /><img src="http://farm4.static.flickr.com/3290/3154787295_16b9c12d98_o.png" alt="The Editor Extension" /><br /><br />In order to bind the Swing component to the SWT Composite, we can use the SWT_AWT Bridge. We will wrap the JTree with an AWT Panel and place that Panel in the Frame returned by the SWT_AWT factory. Also, for this example, we will ensure that all the TreeNodes are expanded in the JTree.<br /><div style="overflow:auto;width:100%;padding-bottom:5px"><br /><pre><br />package timezra.blog.swt_awt_selection_binding.editors;<br /><br />import java.awt.Frame;<br />import java.awt.Panel;<br />import javax.swing.JTree;<br />import org.eclipse.core.runtime.IProgressMonitor;<br />import org.eclipse.swt.SWT;<br />import org.eclipse.swt.awt.SWT_AWT;<br />import org.eclipse.swt.widgets.Composite;<br />import org.eclipse.ui.IEditorInput;<br />import org.eclipse.ui.IEditorSite;<br />import org.eclipse.ui.PartInitException;<br />import org.eclipse.ui.part.EditorPart;<br />import timezra.blog.swt_awt_selection_binding.awt.JTreeFactory;<br /><br />public class JTreeEditor extends EditorPart {<br /><br /> @Override<br /> public void doSave(final IProgressMonitor monitor) {<br /> // no-op<br /> }<br /><br /> @Override<br /> public void doSaveAs() {<br /> // no-op<br /> }<br /><br /> @Override<br /> public void init(final IEditorSite site, final IEditorInput input)<br /> throws PartInitException {<br /> setSite(site);<br /> setInput(input);<br /> }<br /><br /> @Override<br /> public boolean isDirty() {<br /> return false;<br /> }<br /><br /> @Override<br /> public boolean isSaveAsAllowed() {<br /> return false;<br /> }<br /><br /> @Override<br /> public void setFocus() {<br /> // no-op<br /> }<br /><br /> @Override<br /> public void createPartControl(final Composite parent) {<br /> final Panel panel = new Panel();<br /> final JTree jTree = JTreeFactory.create();<br /> panel.add(jTree);<br /> for (int i = 0; i < jTree.getRowCount(); i++) {<br /> jTree.expandRow(i);<br /> }<br /> final Composite container = new Composite(parent, SWT.EMBEDDED);<br /> final Frame frame = SWT_AWT.new_Frame(container);<br /> frame.add(panel);<br /> }<br />}<br /></pre><br /></div><br /><br />If we run with a new Eclipse launch configuration, create a default project and a stub <i>.book</i> file we will now see the Editor with the embedded AWT and Swing components.<br /><img src="http://farm4.static.flickr.com/3257/3155624068_d5d6ab2e90_o.png" alt="The JTree embedded in an Eclipse Editor"><br /><br /><h4>Create a SelectionProvider</h4><br />We are ready to create a JTreeSelectionProvider which listens for AWT selection events and broadcasts those events to the Eclipse Workbench. Note that the TreeSelectionAdapter is responsible for ensuring that SelectionChangedEvents are dispatched on the SWT Display thread; otherwise, the events will be dispatched on the AWT Event Thread.<br /><div style="overflow:auto;width:100%;padding-bottom:5px"><br /><pre><br />package timezra.blog.swt_awt_selection_binding.editors;<br /><br />import java.util.ArrayList;<br />import java.util.HashMap;<br />import java.util.List;<br />import java.util.Map;<br />import javax.swing.JTree;<br />import javax.swing.event.TreeSelectionEvent;<br />import javax.swing.event.TreeSelectionListener;<br />import javax.swing.tree.DefaultMutableTreeNode;<br />import javax.swing.tree.TreePath;<br />import org.eclipse.jface.viewers.ISelection;<br />import org.eclipse.jface.viewers.ISelectionChangedListener;<br />import org.eclipse.jface.viewers.ISelectionProvider;<br />import org.eclipse.jface.viewers.SelectionChangedEvent;<br />import org.eclipse.jface.viewers.StructuredSelection;<br />import org.eclipse.swt.widgets.Display;<br /><br />class JTreeSelectionProvider implements ISelectionProvider {<br /><br /> private final Map<ISelectionChangedListener, TreeSelectionListener> swt2Swing;<br /> private final JTree tree;<br /><br /> JTreeSelectionProvider(final JTree tree) {<br /> this.tree = tree;<br /> swt2Swing = new HashMap<ISelectionChangedListener, TreeSelectionListener>();<br /> }<br /><br /> public void addSelectionChangedListener(<br /> final ISelectionChangedListener listener) {<br /> final TreeSelectionAdapter adapter = new TreeSelectionAdapter(listener);<br /> swt2Swing.put(listener, adapter);<br /> tree.addTreeSelectionListener(adapter);<br /> }<br /><br /> public void removeSelectionChangedListener(<br /> final ISelectionChangedListener listener) {<br /> tree.removeTreeSelectionListener(swt2Swing.get(listener));<br /> }<br /><br /> public ISelection getSelection() {<br /> final TreePath[] paths = tree.getSelectionPaths();<br /> if (paths == null) {<br /> return StructuredSelection.EMPTY;<br /> }<br /> final List<Object> selections = new ArrayList<Object>();<br /> for (final TreePath path : paths) {<br /> selections.add(((DefaultMutableTreeNode) path.getLastPathComponent())<br /> .getUserObject());<br /> }<br /> return new StructuredSelection(selections);<br /> }<br /><br /> public void setSelection(final ISelection selection) {<br /> // not yet implemented<br /> }<br /><br /> private final class TreeSelectionAdapter implements TreeSelectionListener {<br /><br /> private final ISelectionChangedListener listener;<br /><br /> TreeSelectionAdapter(final ISelectionChangedListener listener) {<br /> this.listener = listener;<br /> }<br /><br /> public void valueChanged(final TreeSelectionEvent e) {<br /> Display.getDefault().asyncExec(new Runnable() {<br /> @Override<br /> public void run() {<br /> listener.selectionChanged(new SelectionChangedEvent(<br /> JTreeSelectionProvider.this, getSelection()));<br /> }<br /> });<br /> }<br /> }<br />}<br /></pre><br /></div><br /><br />We may then register this ISelectionProvider with our Eclipse Editor Site.<br /><div style="overflow:auto;width:100%;padding-bottom:5px"><br /><pre><br />public class JTreeEditor extends EditorPart {<br /> ....<br /> public void createPartControl(final Composite parent) {<br /> ....<br /> getSite().setSelectionProvider(new JTreeSelectionProvider(jTree));<br /> }<br /> ....<br />}<br /></pre><br /></div><br /><br /><h4>Create a Command</h4><br />To test whether the provider properly propagates selection events, we can create a new Command. For our test, the command should only be enabled if a single BookInfo is selected. All the command contribution and enablement information can be configured through extension points. <br />Here, the command handler is enabled when exactly one instance of BookInfo is selected. <br /><img src="http://farm4.static.flickr.com/3126/3155624090_691e5a20b5_o.png" alt="The Command Contribution and Enablement Configuration."/><br /><br />The command handler implementation displays the Book information in a message dialog.<br /><div style="overflow:auto;width:100%;padding-bottom:5px"><br /><pre><br />package timezra.blog.swt_awt_selection_binding.handlers;<br /><br />import org.eclipse.core.commands.AbstractHandler;<br />import org.eclipse.core.commands.ExecutionEvent;<br />import org.eclipse.core.commands.ExecutionException;<br />import org.eclipse.jface.dialogs.MessageDialog;<br />import org.eclipse.jface.viewers.IStructuredSelection;<br />import org.eclipse.ui.IWorkbenchWindow;<br />import org.eclipse.ui.handlers.HandlerUtil;<br />import timezra.blog.swt_awt_selection_binding.awt.BookInfo;<br /><br />public class BookInfoSelectionHandler extends AbstractHandler {<br /> public Object execute(final ExecutionEvent event) throws ExecutionException {<br /> final IWorkbenchWindow window = HandlerUtil<br /> .getActiveWorkbenchWindowChecked(event);<br /> final BookInfo book = (BookInfo) ((IStructuredSelection) HandlerUtil<br /> .getCurrentSelectionChecked(event)).getFirstElement();<br /> MessageDialog.openInformation(window.getShell(), "Book Info", book<br /> .toString());<br /> return null;<br /> }<br />}<br /></pre><br /></div><br /><br />If we run with our SWT_AWT launch configuration again, this time, we will notice the new command contribution and we will see that the selection of different TreeNodes affects the behavior of the command contribution.<br />When no BookInfo is selected, the command is disabled.<br /><img src="http://farm4.static.flickr.com/3088/3155624112_9d7036a175_o.png" alt="When no BookInfo is selected, the command is disabled."><br /><br />When exactly one BookInfo is selected, the command is enabled.<br /><img src="http://farm4.static.flickr.com/3266/3155624128_c5dee6a0ca_o.png" alt="When exactly one BookInfo is selected, the command is enabled."><br /><br />The BookInfo is displayed in a message dialog.<br /><img src="http://farm4.static.flickr.com/3212/3154787397_5585de41e9_o.png" alt="The BookInfo is displayed in a message dialog.">Tim Myerhttp://www.blogger.com/profile/01514263555690798238noreply@blogger.com4