<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>Restafarian.org</title>
	
	<link>http://blog.restafarian.org</link>
	<description>What’s in a name? That which we call a rose By any other name would smell as sweet.</description>
	<pubDate>Thu, 18 Dec 2008 00:48:48 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/Restafarianorg" type="application/rss+xml" /><item>
		<title>Spring BlazeDS Integration 1.0.0.M1 Released</title>
		<link>http://feeds.feedburner.com/~r/Restafarianorg/~3/488162021/</link>
		<comments>http://blog.restafarian.org/2008/12/spring-blazeds-integration-100m1-released/#comments</comments>
		<pubDate>Thu, 18 Dec 2008 00:48:48 +0000</pubDate>
		<dc:creator>Restamon</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://blog.restafarian.org/?p=386</guid>
		<description>Speaking of something to start taking a look at, check this out:
Dear Spring Community,
I&amp;#8217;m pleased to announce that the first public development milestone of Spring BlazeDS Integration, the newest member of the open source Spring portfolio, is now available.
Download &amp;#124; Reference Documentation &amp;#124; JavaDocs &amp;#124; Changelog 
This is a foundational release that sets the stage [...]</description>
			<content:encoded><![CDATA[<p>Speaking of <a title="First Spring Framework 3.0 milestone released" href="http://blog.restafarian.org/2008/12/first-spring-framework-30-milestone-released/" target="_self">something to start taking a look at</a>, check <a title="http://www.springsource.org/node/904" href="http://www.springsource.org/node/904" target="_blank">this</a> out:</p>
<blockquote><p>Dear Spring Community,</p>
<p>I&#8217;m pleased to announce that the first public development milestone of <a href="http://www.springsource.org/spring-flex">Spring BlazeDS Integration</a>, the newest member of the open source Spring portfolio, is now available.<br />
<a href="http://www.springsource.com/download/community?project=Spring%20BlazeDS%20Integration">Download</a> | <a href="http://static.springframework.org/spring-flex/docs/1.0.x/reference/html/index.html">Reference Documentation</a> | <a href="http://static.springframework.org/spring-flex/docs/1.0.x/javadoc-api/index.html">JavaDocs</a> | <a href="http://static.springframework.org/spring-flex/docs/1.0.x/changelog.txt">Changelog </a></p>
<p>This is a foundational release that sets the stage for using Adobe Flex and BlazeDS in conjunction with the Spring programming model to build Rich Internet Applications.  We have a number of further integration ideas in mind already for the next milestone, and I would like to invite the community to get involved by trying out this early preview and giving us feedback in the <a href="http://forum.springframework.org/forumdisplay.php?f=61">community forum</a> and <a href="http://jira.springframework.org/browse/flex">Jira</a> as we progress towards a full-fledged 1.0.  Check out <a href="http://blog.springsource.com/2008/12/17/using-spring-blazeds-integration-m1/">Using Spring BlazeDS Integration 1.0.0.M1</a> to get started.</p>
<p>Jeremy Grelle<br />
Spring BlazeDS Integration Lead</p></blockquote>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Restafarianorg?a=ixsoO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=ixsoO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=lbdvO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=lbdvO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=9tNfO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=9tNfO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=7R8JO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=7R8JO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=yFUzO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=yFUzO" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Restafarianorg/~4/488162021" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.restafarian.org/2008/12/spring-blazeds-integration-100m1-released/feed/</wfw:commentRss>
		<feedburner:origLink>http://blog.restafarian.org/2008/12/spring-blazeds-integration-100m1-released/</feedburner:origLink></item>
		<item>
		<title>First Spring Framework 3.0 milestone released</title>
		<link>http://feeds.feedburner.com/~r/Restafarianorg/~3/478712134/</link>
		<comments>http://blog.restafarian.org/2008/12/first-spring-framework-30-milestone-released/#comments</comments>
		<pubDate>Mon, 08 Dec 2008 18:36:27 +0000</pubDate>
		<dc:creator>Restamon</dc:creator>
		
		<category><![CDATA[General]]></category>

		<guid isPermaLink="false">http://blog.restafarian.org/?p=384</guid>
		<description>Just when I was looking for something to do, along comes this:
I&amp;#8217;m pleased to announce that Spring Framework 3.0 M1 is finally available for download!
This release features several major changes, including a start of the major 3.0 themes such as EL and REST support:

revised project layout and build system with module-based sources
updated entire codebase for [...]</description>
			<content:encoded><![CDATA[<p>Just when I was <a title="Notification Service: Now what (again!)?" href="http://blog.restafarian.org/2008/12/notification-service-now-what-again/" target="_self">looking for something to do</a>, along comes <a title="http://blog.springsource.com/2008/12/05/spring-framework-30-m1-released/" href="http://blog.springsource.com/2008/12/05/spring-framework-30-m1-released/" target="_blank">this</a>:</p>
<blockquote><p>I&#8217;m pleased to announce that Spring Framework 3.0 M1 is finally available for <a onclick="javascript:urchinTracker('/outbound/www.springsource.com');" href="http://www.springsource.com/download/community?project=Spring%20Framework">download</a>!</p>
<p>This release features several major changes, including a start of the major 3.0 themes such as <strong>EL and REST support</strong>:</p>
<ul>
<li>revised project layout and build system with <strong>module-based sources</strong></li>
<li>updated entire codebase for <strong>Java 5 code style</strong> (generics, varargs)</li>
<li>updated to <strong>JUnit 4.5</strong> and JRuby 1.1</li>
<li>introduced <strong>Spring EL parser</strong> (<em>org.springframework.expression</em> package)</li>
<li>introduced support for <strong>#{…} expressions in bean definitions</strong></li>
<li>introduced <strong>expression-enabled @Value annotation</strong> for embedded expressions</li>
<li>introduced <strong>@PathVariable annotation for URI template handling</strong> in MVC handlers</li>
<li>introduced <strong>default value support for @RequestParam</strong> in MVC handlers</li>
<li>introduced <strong>@RequestHeader annotation for HTTP header access</strong> in MVC handlers</li>
<li>introduced <strong>AbstractAtomFeedView and AbstractRssFeedView</strong> base classes</li>
<li>introduced <strong>&lt;spring:url&gt; and &lt;spring:param&gt;</strong> JSP tags</li>
</ul>
<p>as well as various minor enhancements.</p>
<p>Note that Spring Framework 3.0 requires Java 5 or above and J2EE 1.4 or above. We are building on Java 6 and Java EE 5 as the primary platform levels - but rest assured, we will retain compatibility with Java 5 enabled J2EE 1.4 servers such as WebLogic 9 and WebSphere 6.1.</p></blockquote>
<p>This definitely looks like something to start taking a look at.</p>
<p>But then, everything new and cool seems to me like something worth taking a look at. Focus &#8230; must &#8230; fight &#8230; ADD &#8230; focus &#8230; breathe &#8230; focus &#8230;</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Restafarianorg?a=MCMPO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=MCMPO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=Frh2O"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=Frh2O" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=ULEqO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=ULEqO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=tj99O"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=tj99O" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=Y91qO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=Y91qO" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Restafarianorg/~4/478712134" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.restafarian.org/2008/12/first-spring-framework-30-milestone-released/feed/</wfw:commentRss>
		<feedburner:origLink>http://blog.restafarian.org/2008/12/first-spring-framework-30-milestone-released/</feedburner:origLink></item>
		<item>
		<title>Notification Service: Now what (again!)?</title>
		<link>http://feeds.feedburner.com/~r/Restafarianorg/~3/477701833/</link>
		<comments>http://blog.restafarian.org/2008/12/notification-service-now-what-again/#comments</comments>
		<pubDate>Sun, 07 Dec 2008 18:36:22 +0000</pubDate>
		<dc:creator>Restamon</dc:creator>
		
		<category><![CDATA[General]]></category>

		<category><![CDATA[notification]]></category>

		<category><![CDATA[Notification Service]]></category>

		<category><![CDATA[service]]></category>

		<guid isPermaLink="false">http://blog.restafarian.org/?p=381</guid>
		<description>Yes, I know &amp;#8212; we&amp;#8217;ve been here before, but since that time, we actually ticked off the first item on the list, so now it is time once again to contemplate where things go from here. We could just keep going down that list of items to the next issue and start making some additional [...]</description>
			<content:encoded><![CDATA[<p>Yes, I know &#8212; <a title="Notification Service: Now what?" href="http://blog.restafarian.org/2008/11/notification-service-now-what/" target="_self">we&#8217;ve been here before</a>, but since that time, we actually ticked off the first item on the list, so now it is time once again to contemplate where things go from here. We could just keep going down that list of items to the next issue and start making some additional <a title="Notification Service: MessageCourier" href="http://blog.restafarian.org/2008/11/notification-service-messagecourier/" target="_self">message couriers</a>, which would be fun, or we could just skip that for now and move on to something else.</p>
<p>One thing I forgot to mention in the last version of this post was the idea of <a title="Notification Service: To wait or not to wait ..." href="http://blog.restafarian.org/2008/11/notification-service-to-wait-or-not-to-wait/" target="_self">spinning off a separate thread</a> for sending out the notices. That&#8217;s another one of those things that I would really like to do, but like a number of such issues, I&#8217;ve just set off to the side in the interest of getting something to the point of actually working before investing too much in the bells and whistles. Now might be a good time to go back and explore that a little bit.</p>
<p>Another thing that I thought about doing was to build a few more example notice templates, particularly since <a title="http://velocity.apache.org/news.html#engine16" href="http://velocity.apache.org/news.html#engine16" target="_blank">Velocity 1.6 is now out</a>. It would be fun to work up a few sample templates that leveraged some of the new capabilities the 1.6 release. But then, that thought got me thinking about the various applications for the notification service, and how all of the little services that we have built so far could leverage off of one another, and what kind of sample app could be constructed to best illustrate such use.  Which got me thinking &#8230;</p>
<p>Before I started <a title="Fun with Subversion" href="http://blog.restafarian.org/2008/05/fun-with-subversion/" target="_self">putting the source code out on Subversion</a>, I used to <a title="The Authorization Service: All wrapped up!" href="http://blog.restafarian.org/2008/03/the-authorization-service-all-wrapped-up/" target="_self">release a complete .ear file</a>, including all of the source code. I stopped doing that because, for one, now you can just connect to Subversion and pull down the source code yourself, and for another, now I <a title="Moving to Maven" href="http://blog.restafarian.org/2008/04/moving-to-maven/" target="_self">produce the .ear file using Maven</a>, and I&#8217;ve never taken the time to figure out how to produce an .ear file using Maven that includes the source code. So, I just stopped doing that.</p>
<p>The point, here, though, that I was trying to get to in my rambling, convoluted way, is that I was thinking that maybe, instead of an .ear file full of source code, I should release a different kind of file &#8230; a &#8220;demo&#8221; file that included an application server and a database (presumably <a title="http://tomcat.apache.org/" href="http://tomcat.apache.org/" target="_blank">Tomcat</a> and <a title="http://hsqldb.org/" href="http://hsqldb.org/" target="_blank">HSSQLDB</a>) that you could just unzip and fire up and get to all of the examples. That would seem to be more useful than an .ear file that you would have to deploy to your own server, and would be a much faster path to seeing some of these examples actually work.</p>
<p>Of course, I would want to upgrade all of the examples, and come up with a little nicer way to launch them all and explain them all, but still, that&#8217;s an interesting idea. One that would undoubtedly take a considerable amount of work to set up, but even so, an interesting idea. Something to consider, anyway.</p>
<p>Which brings us back to that same old question: what to do next?!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Restafarianorg?a=6yTpO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=6yTpO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=4rhNO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=4rhNO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=LGoRO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=LGoRO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=3Vo8O"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=3Vo8O" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=wkFCO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=wkFCO" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Restafarianorg/~4/477701833" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.restafarian.org/2008/12/notification-service-now-what-again/feed/</wfw:commentRss>
		<feedburner:origLink>http://blog.restafarian.org/2008/12/notification-service-now-what-again/</feedburner:origLink></item>
		<item>
		<title>Notification Service: The audit log in action</title>
		<link>http://feeds.feedburner.com/~r/Restafarianorg/~3/476762516/</link>
		<comments>http://blog.restafarian.org/2008/12/notification-service-the-audit-log-in-action/#comments</comments>
		<pubDate>Sat, 06 Dec 2008 16:35:47 +0000</pubDate>
		<dc:creator>Restamon</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[audit log]]></category>

		<category><![CDATA[notification]]></category>

		<category><![CDATA[Notification Service]]></category>

		<category><![CDATA[service]]></category>

		<guid isPermaLink="false">http://blog.restafarian.org/?p=376</guid>
		<description>With the completion of the service layer for the audit log, it was now time to make a few changes to the Notifier implementation to log the details of notifications. While I was at it, I also upgraded to Velocity 1.6, since that became available this week, just in time for my little Notification Service [...]</description>
			<content:encoded><![CDATA[<p>With the completion of the service layer for the audit log, it was now time to make <a title="http://trac2.assembla.com/restafarian/changeset?old_path=notify%2Ftrunk%2Fsrc%2Fmain%2Fjava%2Forg%2Frestafarian%2Fnotify%2Fservice%2Fimpl%2FNotifierImpl.java&amp;old=222&amp;new_path=notify%2Ftrunk%2Fsrc%2Fmain%2Fjava%2Forg%2Frestafarian%2Fnotify%2Fservice%2Fimpl%2FNotifierImpl.java&amp;new=223" href="http://trac2.assembla.com/restafarian/changeset?old_path=notify%2Ftrunk%2Fsrc%2Fmain%2Fjava%2Forg%2Frestafarian%2Fnotify%2Fservice%2Fimpl%2FNotifierImpl.java&amp;old=222&amp;new_path=notify%2Ftrunk%2Fsrc%2Fmain%2Fjava%2Forg%2Frestafarian%2Fnotify%2Fservice%2Fimpl%2FNotifierImpl.java&amp;new=223" target="_blank">a few changes</a> to the <a title="http://trac2.assembla.com/restafarian/browser/notify/trunk/src/main/java/org/restafarian/notify/service/impl/NotifierImpl.java?rev=223" href="http://trac2.assembla.com/restafarian/browser/notify/trunk/src/main/java/org/restafarian/notify/service/impl/NotifierImpl.java?rev=223" target="_blank">Notifier implementation</a> to log the details of notifications. While I was at it, I also upgraded to <a title="http://velocity.apache.org/" href="http://velocity.apache.org/" target="_blank">Velocity</a> 1.6, since <a title="http://velocity.apache.org/news.html#engine16" href="http://velocity.apache.org/news.html#engine16" target="_blank">that became available</a> this week, just in time for my little <a title="Notification Service: Overview" href="http://blog.restafarian.org/2008/10/notification-service-overview/" target="_self">Notification Service</a> (which, I am sure, was their intent!). Here is the major element of the change:</p>
<pre>  /**
   * &lt;p&gt;Logs the details of this notification.&lt;/p&gt;
   *
   * @param deliveryMethod the delivery method used for this message
   * @param addresses an array of "address" objects containing the
   * implementation-specific addresses required for successful delivery of
   * the message
   * @param titleSubject an optional subject and/or title of the message to
   * be delivered
   * @param contentType the mime type of the message body
   * @param body the text of the message to be delivered
   * @param noticeData optional data used to resolve variables in the notice
   */
  private void auditNotification(String deliveryMethod, MessageAddress[] addresses,
         String titleSubject,  String contentType, String body, Object noticeData) {
    NoticeAudit noticeAudit = new NoticeAudit();

    Date rightNow = new Date();
    String userId = "NotifierImpl";
    HttpServletRequest req = findHttpServletRequest(noticeData);
    if (req != null) {
      if (StringUtils.isNotEmpty(req.getRemoteUser())) {
        userId = req.getRemoteUser();
        noticeAudit.setRemoteAddr(req.getRemoteAddr());
        noticeAudit.setRemoteHost(req.getRemoteHost());
        noticeAudit.setRemoteUser(req.getRemoteUser());
      }
    }
    noticeAudit.setStackTrace(getStackTraceString());
    noticeAudit.setAddressing(formatAddresses(addresses));
    noticeAudit.setContentType(contentType);
    noticeAudit.setDeliveryMethod(deliveryMethod);
    noticeAudit.setTitleSubject(titleSubject);
    noticeAudit.setBody(body);
    noticeAudit.setCreationDate(rightNow);
    noticeAudit.setCreatedBy(userId);
    noticeAudit.setLastUpdate(rightNow);
    noticeAudit.setLastUpdateBy(userId);

    // save audit details
    noticeAuditManager.save(noticeAudit);
  }</pre>
<p>There are some details behind a few of the properties of the log, some of which I consider done, and others that I consider acceptable for now, but could really use a little more attention at some point. The <em>findHttpServletRequest</em> method is particularly convoluted and could use some work, but my basic thought there was that I did not want to add the HttpServletRequest as yet another parameter in the API, but if I could find it, I wanted to use it to log a few things that you can find there. So, I set up this little routine to hunt through the <em>noticeData</em> object, which can be literally anything, in an effort to see if I could locate an HttpServletRequest object:</p>
<pre>  /**
   * &lt;p&gt;Returns the HttpServletRequest, if it can be located.&lt;/p&gt;
   *
   * @param noticeData optional data used to resolve variables in the notice
   * @return the HttpServletRequest, if it can be located
   */
  @SuppressWarnings("unchecked")
  private static HttpServletRequest findHttpServletRequest(Object noticeData) {
    HttpServletRequest request = null;

    try {
      // first, see if the noticeData is the request itself
      request = (HttpServletRequest) noticeData;
    } catch (ClassCastException e) {
      try {
        // next, see if the noticeData is a map
        Map noticeDataMap = (Map) noticeData;
        Iterator i = noticeDataMap.keySet().iterator();
        while (request == null &amp;&amp; i.hasNext()) {
          Object key  = i.next();
          try {
            // then, see if the map element is the request object
            request = (HttpServletRequest) noticeDataMap.get(key);
          } catch (ClassCastException e1) {
            // ... and if not, see if the map element is another map
            Map noticeDataSubMap = (Map) noticeDataMap.get(key);
            Iterator j = noticeDataSubMap.keySet().iterator();
            while (request == null &amp;&amp; j.hasNext()) {
              Object subkey  = j.next();
              try {
                // then, see if the map element's map element is the request object
                request = (HttpServletRequest) noticeDataSubMap.get(subkey);
              } catch (ClassCastException e2) {
                // ... and if that's not it, then give up!
              }
            }
          }
        }
      } catch (ClassCastException e1) {
        // no one cares
      }
    }

    return request;
  }</pre>
<p>I didn&#8217;t put much thought into that one, and I should probably spend a little more time on that process at some point, but I think it will do the job for now. The other area that will need some work one day is the answer to the question &#8220;Should we log this?&#8221; Right now, I set up a global variable and answered the question in this way:</p>
<pre>  /**
   * &lt;p&gt;Returns true if this notice should be audited.&lt;/p&gt;
   *
   * @param sendFrom the "from" address
   * @param sendTo the list of objects representing the notice recipients
   * @param sendToProperty the name of the property in the recipient object
   * that specifies the "to" address. If this parameter is null or blank, it
   * is assumed that the sendTo list contains simple "to" address strings
   * @param noticeTemplate the notice template
   * @param noticeData optional data used to resolve variables in the notice
   * @return true if this notice should be audited
   */
  private boolean isAuditLogActive(String sendFrom, List&lt;Object&gt; sendTo, String sendToProperty,
         NoticeTemplate noticeTemplate, Object noticeData) {
    return "true".equals(auditNotifications);
  }</pre>
<p>In the future, I&#8217;d like to provide some way to make that decision on more of a case-by-case basis, depending on such things as template id, from address, to address, delivery method, calling module, or maybe even some flag passed in some way that says &#8220;Audit this&#8221; or &#8220;Don&#8217;t audit this.&#8221; I hadn&#8217;t really thought any of that through to completion, so I just passed everything that I had available to this method and didn&#8217;t reference any of it for now, but stuck it all in there anyway, just so that I would have it available. (I know &#8230; that&#8217;s a bad thing to do, philosophically speaking, but I still did it!)</p>
<p>Turning auditing off and on is one of those critical little things that needs to be as flexible as possible. Auditing consumes a considerable amount of overhead and storage, and you need to be able to finely control what gets audited and what doesn&#8217;t if the feature is going to be of any use at all. My global yes-or-no for everything approach is good for testing, but there has to be something a lot more ganular than that, or it&#8217;s just going to be &#8220;No&#8221; always. There definitely needs to be a lot more work done in that area.</p>
<p>But not today!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Restafarianorg?a=dpSVO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=dpSVO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=C45YO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=C45YO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=uu2PO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=uu2PO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=wg6aO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=wg6aO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=rAsCO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=rAsCO" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Restafarianorg/~4/476762516" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.restafarian.org/2008/12/notification-service-the-audit-log-in-action/feed/</wfw:commentRss>
		<feedburner:origLink>http://blog.restafarian.org/2008/12/notification-service-the-audit-log-in-action/</feedburner:origLink></item>
		<item>
		<title>Notification Service: Audit log data manager tests</title>
		<link>http://feeds.feedburner.com/~r/Restafarianorg/~3/476022051/</link>
		<comments>http://blog.restafarian.org/2008/12/notification-service-audit-log-data-manager-tests/#comments</comments>
		<pubDate>Fri, 05 Dec 2008 20:33:08 +0000</pubDate>
		<dc:creator>Restamon</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[junit]]></category>

		<category><![CDATA[notification]]></category>

		<category><![CDATA[Notification Service]]></category>

		<category><![CDATA[service]]></category>

		<category><![CDATA[service layer]]></category>

		<category><![CDATA[unit test]]></category>

		<guid isPermaLink="false">http://blog.restafarian.org/?p=374</guid>
		<description>Now that we have the NoticeAuditManager and NoticeAuditManagerImpl, we need to test them. First, the NoticeAuditManagerTest:
package org.restafarian.notify.manager;

import java.util.Date;

import org.restafarian.notify.beans.NoticeAudit;
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;

public class NoticeAuditManagerTest extends AbstractTransactionalDataSourceSpringContextTests {
  private NoticeAuditManager noticeAuditManager;

  public void setNoticeAuditManager(NoticeAuditManager noticeAuditManager) {
    this.noticeAuditManager = noticeAuditManager;
  }

  protected String[] getConfigLocations() {
    setAutowireMode(AUTOWIRE_BY_NAME);
    [...]</description>
			<content:encoded><![CDATA[<p>Now that we have the <a title="Notification Service: Audit log data manager" href="http://blog.restafarian.org/2008/12/notification-service-audit-log-data-manager/" target="_self">NoticeAuditManager and NoticeAuditManagerImpl</a>, we need to test them. First, the <em>NoticeAuditManagerTest</em>:</p>
<pre>package org.restafarian.notify.manager;

import java.util.Date;

import org.restafarian.notify.beans.NoticeAudit;
import org.springframework.test.AbstractTransactionalDataSourceSpringContextTests;

public class NoticeAuditManagerTest extends AbstractTransactionalDataSourceSpringContextTests {
  private NoticeAuditManager noticeAuditManager;

  public void setNoticeAuditManager(NoticeAuditManager noticeAuditManager) {
    this.noticeAuditManager = noticeAuditManager;
  }

  protected String[] getConfigLocations() {
    setAutowireMode(AUTOWIRE_BY_NAME);
    return new String[] {"classpath*:/context/applicationContext*.xml"};
  }

  protected void onSetUpInTransaction() throws Exception {
    deleteFromTables(new String[]{"noticetemplate"});
  }

  public void testGetNoticeAudits() {
    Date rightNow = new Date();
    String userId = "NoticeAuditEntryManagerTest";
    NoticeAudit noticeAudit1 = new NoticeAudit();
    noticeAudit1.setRemoteAddr("127.0.0.1");
    noticeAudit1.setRemoteHost("localhost");
    noticeAudit1.setRemoteUser("testuser");
    noticeAudit1.setStackTrace(getStackTraceString());
    noticeAudit1.setAddressing("mailFrom: testuser@localhost\nmailTo: testuser@localhost");
    noticeAudit1.setContentType("text/plain");
    noticeAudit1.setDeliveryMethod("email");
    noticeAudit1.setTitleSubject("This is a test audit.");
    noticeAudit1.setBody("This is a test audit.");
    noticeAudit1.setCreationDate(rightNow);
    noticeAudit1.setCreatedBy(userId);
    noticeAudit1.setLastUpdate(rightNow);
    noticeAudit1.setLastUpdateBy(userId);
    NoticeAudit noticeAudit2 = new NoticeAudit();
    noticeAudit2.setRemoteAddr("127.0.0.1");
    noticeAudit2.setRemoteHost("localhost");
    noticeAudit2.setRemoteUser("testuser");
    noticeAudit2.setStackTrace(getStackTraceString());
    noticeAudit2.setAddressing("mailFrom: testuser@localhost\nmailTo: testuser@localhost");
    noticeAudit2.setContentType("text/hmtl");
    noticeAudit2.setDeliveryMethod("email");
    noticeAudit2.setTitleSubject("This is another test audit.");
    noticeAudit2.setBody("&lt;html&gt;&lt;body&gt;&lt;p&gt;This is a test audit.&lt;/p&gt;&lt;body&gt;&lt;/html&gt;");
    noticeAudit2.setCreationDate(rightNow);
    noticeAudit2.setCreatedBy(userId);
    noticeAudit2.setLastUpdate(rightNow);
    noticeAudit2.setLastUpdateBy(userId);
    noticeAuditManager.save(noticeAudit1);
    noticeAuditManager.save(noticeAudit2);

    assertEquals(2, noticeAuditManager.findAll().size());
  }

  private String getStackTraceString() {
    StringBuffer buffer = new StringBuffer();

    String separator = "";
    StackTraceElement[] element = Thread.currentThread().getStackTrace();
    for (int i=0; i&lt;element.length; i++) {
      buffer.append(separator);
      buffer.append(element[i].toString());
      separator = "\n";
    }

    return buffer.toString();
  }
}</pre>
<p>&#8230; followed closely by the <em>NoticeAuditManagerImplTest</em>:</p>
<pre>package org.restafarian.notify.manager.impl;

import java.util.Date;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jmock.Mock;
import org.jmock.MockObjectTestCase;
import org.restafarian.notify.beans.NoticeAudit;
import org.restafarian.notify.dao.NoticeAuditDao;
import org.restafarian.notify.manager.impl.NoticeAuditManagerImpl;
import org.springframework.dao.DataAccessException;
import org.springframework.orm.ObjectRetrievalFailureException;

public class NoticeAuditManagerImplTest extends MockObjectTestCase {
  private final Log log = LogFactory.getLog(NoticeAuditManagerImplTest.class);
  private NoticeAuditManagerImpl mgr = new NoticeAuditManagerImpl();
  private Mock mockDao = null;

  protected void setUp() throws Exception {
    mockDao = new Mock(NoticeAuditDao.class);
    mgr.setNoticeAuditDao((NoticeAuditDao) mockDao.proxy());
  }

  public void testAddAndRemoveNoticeAudit() throws Exception {
    Date rightNow = new Date();
    String userId = "NoticeAuditEntryManagerImplTest";
    NoticeAudit noticeAudit = new NoticeAudit();
    noticeAudit.setRemoteAddr("127.0.0.1");
    noticeAudit.setRemoteHost("localhost");
    noticeAudit.setRemoteUser("testuser");
    noticeAudit.setStackTrace(getStackTraceString());
    noticeAudit.setAddressing("mailFrom: testuser@localhost\nmailTo: testuser@localhost");
    noticeAudit.setContentType("text/plain");
    noticeAudit.setDeliveryMethod("email");
    noticeAudit.setTitleSubject("This is a test audit.");
    noticeAudit.setBody("This is a test audit.");
    noticeAudit.setCreationDate(rightNow);
    noticeAudit.setCreatedBy(userId);
    noticeAudit.setLastUpdate(rightNow);
    noticeAudit.setLastUpdateBy(userId);

    // set expected behavior on dao
    mockDao.expects(once()).method("save").with(same(noticeAudit));

    mgr.save(noticeAudit);

    // verify expectations
    mockDao.verify();

    assertEquals(noticeAudit.getTitleSubject(), "This is a test audit.");

    if (log.isDebugEnabled()) {
      log.debug("removing noticeAudit ...");
    }

    int id = noticeAudit.getId();
    mockDao.expects(once()).method("delete").with(eq(noticeAudit));

    mgr.delete(noticeAudit);

    // verify expectations
    mockDao.verify();

    try {
      // set expectations
      Throwable ex = new ObjectRetrievalFailureException(NoticeAudit.class, new Integer(id));
      mockDao.expects(once()).method("findById").with(eq(new Integer(id)))
           .will(throwException(ex));

      noticeAudit = mgr.findById(id);

      // verify expectations
      mockDao.verify();
      fail("NoticeAudit 'testtemplate1' found in database");
    } catch (DataAccessException dae) {
      log.debug("Expected exception: " + dae.getMessage());
      assertNotNull(dae);
    }
  }

  private String getStackTraceString() {
    StringBuffer buffer = new StringBuffer();

    String separator = "";
    StackTraceElement[] element = Thread.currentThread().getStackTrace();
    for (int i=0; i&lt;element.length; i++) {
      buffer.append(separator);
      buffer.append(element[i].toString());
      separator = "\n";
    }

    return buffer.toString();
  }
}</pre>
<p>That takes care of the service layer for the audit log, so now I guess all that is left is to actually do something with it. Time to start taking a second look at the <a title="http://trac2.assembla.com/restafarian/browser/notify/trunk/src/main/java/org/restafarian/notify/service/impl/NotifierImpl.java" href="http://trac2.assembla.com/restafarian/browser/notify/trunk/src/main/java/org/restafarian/notify/service/impl/NotifierImpl.java" target="_blank">Notifier</a> &#8230;</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Restafarianorg?a=gKAuO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=gKAuO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=osfJO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=osfJO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=60reO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=60reO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=oDLjO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=oDLjO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=80XIO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=80XIO" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Restafarianorg/~4/476022051" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.restafarian.org/2008/12/notification-service-audit-log-data-manager-tests/feed/</wfw:commentRss>
		<feedburner:origLink>http://blog.restafarian.org/2008/12/notification-service-audit-log-data-manager-tests/</feedburner:origLink></item>
		<item>
		<title>Notification Service: Audit log data manager</title>
		<link>http://feeds.feedburner.com/~r/Restafarianorg/~3/475345196/</link>
		<comments>http://blog.restafarian.org/2008/12/notification-service-audit-log-data-manager/#comments</comments>
		<pubDate>Fri, 05 Dec 2008 04:30:56 +0000</pubDate>
		<dc:creator>Restamon</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[notification]]></category>

		<category><![CDATA[Notification Service]]></category>

		<category><![CDATA[service]]></category>

		<guid isPermaLink="false">http://blog.restafarian.org/?p=372</guid>
		<description>Meanwhile, back on the Notification Service project, it was time start putting together the service layer on top of the new data access layer for the NoticeAudit entity. Here is the basic manager interface:
package org.restafarian.notify.manager;

import java.util.List;

import org.restafarian.notify.beans.NoticeAudit;

/**
 * &amp;#60;p&amp;#62;This is the NoticeAudit manager interface.&amp;#60;/p&amp;#62;
 */
public interface NoticeAuditManager {

  /**
   * &amp;#60;p&amp;#62;Returns all [...]</description>
			<content:encoded><![CDATA[<p>Meanwhile, back on the <a title="Notification Service: Overview" href="http://blog.restafarian.org/2008/10/notification-service-overview/" target="_self">Notification Service</a> project, it was time start putting together the service layer on top of the new data access layer for the <a title="Notification Service: Audit log bean" href="http://blog.restafarian.org/2008/11/notification-service-audit-log-bean/" target="_self">NoticeAudit</a> entity. Here is the basic manager interface:</p>
<pre>package org.restafarian.notify.manager;

import java.util.List;

import org.restafarian.notify.beans.NoticeAudit;

/**
 * &lt;p&gt;This is the NoticeAudit manager interface.&lt;/p&gt;
 */
public interface NoticeAuditManager {

  /**
   * &lt;p&gt;Returns all NoticeAudits in the database.&lt;/p&gt;
   *
   * @return all NoticeAudits in the database
   */
  public List&lt;NoticeAudit&gt; findAll();

  /**
   * &lt;p&gt;Returns all NoticeAudits in the database that
   * match the specified search criteria.&lt;/p&gt;
   *
   * @param noticeAudit an example NoticeAudit
   * @return all NoticeAudits in the database that
   * match the specified search criteria
   */
  public List&lt;NoticeAudit&gt; findByExample(NoticeAudit noticeAudit);

  /**
   * &lt;p&gt;Returns all NoticeAudits in the database that
   * match the specified search criteria.&lt;/p&gt;
   *
   * @param propertyName the name of the specified property
   * @param propertyValue the search value for the specified
   * property
   * @return all NoticeAudits in the database that
   * match the specified search criteria
   */
  public List&lt;NoticeAudit&gt; findByProperty(String propertyName, Object propertyValue);

  /**
   * &lt;p&gt;Returns the NoticeAudit with the specified id.&lt;/p&gt;
   *
   * @param id the id of the requested noticeAudit
   * @return the NoticeAudit with the specified id
   */
  public NoticeAudit findById(int id);

  /**
   * &lt;p&gt;Saves the NoticeAudit passed.&lt;/p&gt;
   *
   * @param noticeAudit the noticeAudit to save
   */
  public void save(NoticeAudit noticeAudit);

  /**
   * &lt;p&gt;Deletes the NoticeAudit with the specified id.&lt;/p&gt;
   *
   * @param noticeAudit the noticeAudit to delete
   */
  public void delete(NoticeAudit noticeAudit);
}</pre>
<p>&#8230; and here is the concrete implementation:</p>
<pre>package org.restafarian.notify.manager.impl;

import java.util.List;

import org.restafarian.notify.beans.NoticeAudit;
import org.restafarian.notify.dao.NoticeAuditDao;
import org.restafarian.notify.manager.NoticeAuditManager;

/**
 * &lt;p&gt;Concrete implementation of the NoticeAudit manager interface.&lt;/p&gt;
 */
public class NoticeAuditManagerImpl implements NoticeAuditManager {
  private NoticeAuditDao dao;

  /**
   * &lt;p&gt;Returns all NoticeAudits in the database.&lt;/p&gt;
   *
   * @return all NoticeAudits in the database
   */
  public List&lt;NoticeAudit&gt; findAll() {
    return dao.findAll();
  }

  /**
   * &lt;p&gt;Returns all NoticeAudits in the database that
   * match the specified search criteria.&lt;/p&gt;
   *
   * @param noticeAudit an example NoticeAudit
   * @return all NoticeAudits in the database that
   * match the specified search criteria
   */
  public List&lt;NoticeAudit&gt; findByExample(NoticeAudit noticeAudit) {
    return dao.findByExample(noticeAudit);
  }

  /**
   * &lt;p&gt;Returns all NoticeAudits in the database that
   * match the specified search criteria.&lt;/p&gt;
   *
   * @param propertyName the name of the specified property
   * @param propertyValue the search value for the specified
   * property
   * @return all NoticeAudits in the database that
   * match the specified search criteria
   */
  public List&lt;NoticeAudit&gt; findByProperty(String propertyName, Object propertyValue) {
    return dao.findByProperty(propertyName, propertyValue);
  }

  /**
   * &lt;p&gt;Returns the NoticeAudit with the specified id.&lt;/p&gt;
   *
   * @param id the id of the requested noticeAudit
   * @return the NoticeAudit with the specified id
   */
  public NoticeAudit findById(int id) {
    return dao.findById(new Integer(id));
  }

  /**
   * &lt;p&gt;Saves the NoticeAudit passed.&lt;/p&gt;
   *
   * @param noticeAudit the noticeAudit to save
   */
  public void save(NoticeAudit noticeAudit) {
    dao.save(noticeAudit);
  }

  /**
   * &lt;p&gt;Deletes the NoticeAudit with the specified id.&lt;/p&gt;
   *
   * @param noticeAudit the noticeAudit to delete
   */
  public void delete(NoticeAudit noticeAudit) {
    dao.delete(noticeAudit);
  }

  public void setNoticeAuditDao(NoticeAuditDao dao) {
    this.dao = dao;
  }
}</pre>
<p>All we need now is a couple of unit tests, and we can call this portion of the audit process complete!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Restafarianorg?a=qmGLO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=qmGLO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=DrxDO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=DrxDO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=Oj9LO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=Oj9LO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=1XjTO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=1XjTO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=JGyxO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=JGyxO" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Restafarianorg/~4/475345196" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.restafarian.org/2008/12/notification-service-audit-log-data-manager/feed/</wfw:commentRss>
		<feedburner:origLink>http://blog.restafarian.org/2008/12/notification-service-audit-log-data-manager/</feedburner:origLink></item>
		<item>
		<title>DAO Refactoring: One final(?) version</title>
		<link>http://feeds.feedburner.com/~r/Restafarianorg/~3/475265975/</link>
		<comments>http://blog.restafarian.org/2008/12/dao-refactoring-one-final-version/#comments</comments>
		<pubDate>Fri, 05 Dec 2008 02:29:38 +0000</pubDate>
		<dc:creator>Restamon</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[dao]]></category>

		<category><![CDATA[dao refactoring]]></category>

		<category><![CDATA[data access object]]></category>

		<category><![CDATA[Hibernate]]></category>

		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://blog.restafarian.org/?p=370</guid>
		<description>For the last little touch to my version of the &amp;#8220;The Best AbstractHibernateDao Ever&amp;#8220;, I pulled the save and delete methods from here:
package org.restafarian.core.dao.hibernate;

import java.io.Serializable;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.util.Assert;

public abstract class AbstractHibernateDao&amp;#60;E&amp;#62; {
  private final Class&amp;#60;E&amp;#62; entityClass;
  private final SessionFactory sessionFactory;

  /**
   * &amp;#60;p&amp;#62;Constructs a [...]</description>
			<content:encoded><![CDATA[<p>For the last little touch to my version of the &#8220;<a href="http://raykrueger.blogspot.com/2007/09/best-abstracthibernatedao-ever.html">The Best AbstractHibernateDao Ever</a>&#8220;, I pulled the save and delete methods from here:</p>
<pre>package org.restafarian.core.dao.hibernate;

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

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.Example;
import org.hibernate.criterion.Restrictions;
import org.springframework.orm.ObjectRetrievalFailureException;
import org.springframework.util.Assert;

public abstract class AbstractHibernateDao&lt;E&gt; {
  private final Class&lt;E&gt; entityClass;
  private final SessionFactory sessionFactory;

  /**
   * &lt;p&gt;Constructs a new &lt;code&gt;AbstractHibernateDao&lt;/code&gt; using the
   * parameters provided.&lt;/p&gt;
   */
  public AbstractHibernateDao(Class&lt;E&gt; entityClass, SessionFactory sessionFactory) {
    Assert.notNull(entityClass, "entityClass must not be null");
    Assert.notNull(sessionFactory, "sessionFactory must not be null");
    this.entityClass = entityClass;
    this.sessionFactory = sessionFactory;
  }

  /**
   * &lt;p&gt;Returns all entities in the database.&lt;/p&gt;
   *
   * @return all entities in the database
   */
  public List&lt;E&gt; findAll() {
    return all();
  }

  /**
   * &lt;p&gt;Returns all entities in the database that
   * match the specified search criteria.&lt;/p&gt;
   *
   * @param referenceObject an example entity
   * @return all entities in the database that
   * match the specified search criteria
   */
  public List&lt;E&gt; findByExample(E referenceObject) {
    Example example = Example.create(referenceObject);
    example.excludeProperty("id");
    return list(criteria().add(example));
  }

  /**
   * &lt;p&gt;Returns all entities in the database that
   * match the specified search criteria.&lt;/p&gt;
   *
   * @param propertyName the name of the specified property
   * @param propertyValue the search value for the specified
   * property
   * @return all entities in the database that
   * match the specified search criteria
   */
  public List&lt;E&gt; findByProperty(String propertyName, Object propertyValue) {
    return list(criteria().add(Restrictions.eq(propertyName, propertyValue)));
  }

  /**
   * &lt;p&gt;Returns the entity with the specified id.&lt;/p&gt;
   *
   * @param id the id of the requested entity
   * @return the entity with the specified id
   */
  public E findById(Serializable id) {
    E requestedObject = get(id);
    if (requestedObject == null) {
      throw new ObjectRetrievalFailureException(entityClass, id);
    }
    return requestedObject;
  }

  /**
   * &lt;p&gt;Returns the entity class.&lt;/p&gt;
   *
   * @return the entity class
   */
  public Class&lt;E&gt; getEntityClass() {
    return entityClass;
  }

  /**
   * &lt;p&gt;Returns a Hibernate Criteria object for the current session.&lt;/p&gt;
   *
   * @return a Hibernate Criteria object for the current session
   */
  protected Criteria criteria() {
    return currentSession().createCriteria(entityClass);
  }

  /**
   * &lt;p&gt;Returns a Hibernate Query object for the current session.&lt;/p&gt;
   *
   * @return a Hibernate Query object for the current session
   */
  protected Query query(String hql) {
    return currentSession().createQuery(hql);
  }

  /**
   * &lt;p&gt;Returns the current session.&lt;/p&gt;
   *
   * @return the current session
   */
  protected Session currentSession() {
    return sessionFactory.getCurrentSession();
  }

  /**
   * &lt;p&gt;Returns all objects of this entity.&lt;/p&gt;
   *
   * @return all objects of this entity
   */
  protected List&lt;E&gt; all() {
    return list(criteria());
  }

  /**
   * &lt;p&gt;Returns all objects of this entity that match the specified criteria.&lt;/p&gt;
   *
   * @param criteria the search criteria
   * @return all objects of this entity that match the specified criteria
   */
  @SuppressWarnings("unchecked")
  protected List&lt;E&gt; list(Criteria criteria) {
    return criteria.list();
  }

  /**
   * &lt;p&gt;Returns all objects of this entity that satisfy the specified query.&lt;/p&gt;
   *
   * @param query the search query
   * @return all objects of this entity that satisfy the specified query
   */
  @SuppressWarnings("unchecked")
  protected List&lt;E&gt; list(Query query) {
    return query.list();
  }

  /**
   * &lt;p&gt;Returns a single instance of this entity that matches the specified
   * criteria.&lt;/p&gt;
   *
   * @param criteria the search criteria
   * @return a single instance of this entity that matches the specified
   * criteria
   */
  @SuppressWarnings("unchecked")
  protected E uniqueResult(Criteria criteria) {
    return (E) criteria.uniqueResult();
  }

  /**
   * &lt;p&gt;Returns a single instance of this entity that satisfies the specified
   * query.&lt;/p&gt;
   *
   * @param query the search query
   * @return a single instance of this entity that satisfies the specified
   * query
   */
  @SuppressWarnings("unchecked")
  protected E uniqueResult(Query query) {
    return (E) query.uniqueResult();
  }

  /**
   * &lt;p&gt;Returns the instance of this entity with the specified id.&lt;/p&gt;
   *
   * @param id the id of the requested entity
   * @return the instance of this entity with the specified id
   */
  @SuppressWarnings("unchecked")
  protected E get(Serializable id) {
    return (E) currentSession().get(entityClass, id);
  }
}</pre>
<p>&#8230; and stuck them into here:</p>
<pre>package org.restafarian.core.dao.hibernate;

import org.hibernate.SessionFactory;

/**
 * &lt;p&gt;Extends the &lt;code&gt;AbstractHibernateDao&lt;/code&gt; to create an update version,
 * adding standard data maintenance methods.&lt;/p&gt;
 */
public abstract class AbstractHibernateUpdateDao&lt;E&gt; extends AbstractHibernateDao&lt;E&gt; {

  /**
   * &lt;p&gt;Constructs a new &lt;code&gt;AbstractHibernateUpdateDao&lt;/code&gt; using the
   * parameters provided.&lt;/p&gt;
   */
  public AbstractHibernateUpdateDao(Class&lt;E&gt; entityClass, SessionFactory sessionFactory) {
    super(entityClass, sessionFactory);
  }

  /**
   * &lt;p&gt;Saves the entity passed.&lt;/p&gt;
   *
   * @param entity the entity to save
   */
  public void save(E entity) {
    currentSession().saveOrUpdate(entity);
  }

  /**
   * &lt;p&gt;Deletes the entity.&lt;/p&gt;
   *
   * @param entity the entity to delete
   */
  public void delete(E entity) {
    currentSession().delete(entity);
  }
}</pre>
<p>Now the original is a &#8220;read only&#8221; version which can be extended to create read-only DAOs, and the abstract extension of that throws in the data maintenance methods, so that one can be used as the basis for DAOs that actually manipulate the data. Since all of the DAOs that I built by extending the original were data maintenance DAOs, I had to go back into each one and extend the new one instead of the old one, but that all went pretty quick and now it&#8217;s done.</p>
<p>At this point, I am calling the DAO refactoring project both complete and a success, and now I am going to get back to whatever it was that I was doing prior to the start of this little detour.</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Restafarianorg?a=ODiUO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=ODiUO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=avJEO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=avJEO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=dWnOO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=dWnOO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=3Q8EO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=3Q8EO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=80DXO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=80DXO" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Restafarianorg/~4/475265975" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.restafarian.org/2008/12/dao-refactoring-one-final-version/feed/</wfw:commentRss>
		<feedburner:origLink>http://blog.restafarian.org/2008/12/dao-refactoring-one-final-version/</feedburner:origLink></item>
		<item>
		<title>DAO Refactoring: OK, that’s the end of that!</title>
		<link>http://feeds.feedburner.com/~r/Restafarianorg/~3/475239581/</link>
		<comments>http://blog.restafarian.org/2008/12/dao-refactoring-ok-thats-the-end-of-that/#comments</comments>
		<pubDate>Fri, 05 Dec 2008 01:43:20 +0000</pubDate>
		<dc:creator>Restamon</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[dao]]></category>

		<category><![CDATA[dao refactoring]]></category>

		<category><![CDATA[Maven]]></category>

		<category><![CDATA[refactoring]]></category>

		<guid isPermaLink="false">http://blog.restafarian.org/?p=368</guid>
		<description>Once I did one, then it was just a matter of going back and doing the same thing to all of the other projects, and then going through the full build process from the top to get to here:
[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] example-parent ........................................ SUCCESS [14.063s]
[INFO] core .................................................. SUCCESS [50.671s]
[INFO] approval .............................................. SUCCESS [7.250s]
[INFO] [...]</description>
			<content:encoded><![CDATA[<p>Once <a title="DAO Refactoring: Finally!" href="http://blog.restafarian.org/2008/12/dao-refactoring-finally/" target="_self">I did one</a>, then it was just a matter of going back and doing the same thing to all of the other projects, and then going through the full build process from the top to get to here:</p>
<pre>[INFO] ------------------------------------------------------------------------
[INFO] Reactor Summary:
[INFO] ------------------------------------------------------------------------
[INFO] example-parent ........................................ SUCCESS [14.063s]
[INFO] core .................................................. SUCCESS [50.671s]
[INFO] approval .............................................. SUCCESS [7.250s]
[INFO] approval-web .......................................... SUCCESS [17.391s]
[INFO] authorization ......................................... SUCCESS [9.531s]
[INFO] authorization-web ..................................... SUCCESS [18.016s]
[INFO] core-web .............................................. SUCCESS [16.937s]
[INFO] example-web ........................................... SUCCESS [23.110s]
[INFO] identity-web .......................................... SUCCESS [1:26.375s]
[INFO] notify ................................................ SUCCESS [47.562s]
[INFO] notify-web ............................................ SUCCESS [28.469s]
[INFO] example ............................................... SUCCESS [4:47.734s]
[INFO] ------------------------------------------------------------------------
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 10 minutes 25 seconds
[INFO] Finished at: Thu Dec 04 17:45:29 PST 2008
[INFO] Final Memory: 12M/45M
[INFO] ------------------------------------------------------------------------</pre>
<p>Now every project boasts this new addition to its <em>pom.xml</em> file, in addition to all of the little things that had to come along to accommodate that:</p>
<pre>    &lt;plugins&gt;
       &lt;plugin&gt;
        &lt;artifactId&gt;maven-compiler-plugin&lt;/artifactId&gt;
        &lt;configuration&gt;
          &lt;source&gt;1.5&lt;/source&gt;
          &lt;target&gt;1.5&lt;/target&gt;
        &lt;/configuration&gt;
      &lt;/plugin&gt;
    &lt;/plugins&gt;</pre>
<p>That should just about finish up the whole refactoring process, although I still think I want to split up the abstract Hibernate DAO into a read-only version and an extension of that for the update version. That should be pretty simple though, and then I can get back to what it was that I was doing before I started down this road of overhauling everything.</p>
<p>Let&#8217;s see now, just what was I doing before that &#8230;</p>
<p><span style="color: #000000;"><span style="font-family: &quot;Lucida Grande&quot;,&quot;Lucida Sans Unicode&quot;,Tahoma,Verdana,sans-serif;"></span></span></p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Restafarianorg?a=gDbeO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=gDbeO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=br3YO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=br3YO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=jbvEO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=jbvEO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=s2YUO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=s2YUO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=eGofO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=eGofO" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Restafarianorg/~4/475239581" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.restafarian.org/2008/12/dao-refactoring-ok-thats-the-end-of-that/feed/</wfw:commentRss>
		<feedburner:origLink>http://blog.restafarian.org/2008/12/dao-refactoring-ok-thats-the-end-of-that/</feedburner:origLink></item>
		<item>
		<title>DAO Refactoring: Finally!</title>
		<link>http://feeds.feedburner.com/~r/Restafarianorg/~3/473156963/</link>
		<comments>http://blog.restafarian.org/2008/12/dao-refactoring-finally/#comments</comments>
		<pubDate>Wed, 03 Dec 2008 03:04:43 +0000</pubDate>
		<dc:creator>Restamon</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[refactoring]]></category>

		<guid isPermaLink="false">http://blog.restafarian.org/?p=366</guid>
		<description>Well, it took a little longer than I care to admit, but I finally got back to here:
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 minute 41 seconds
[INFO] Finished at: Tue Dec 02 18:41:45 PST 2008
[INFO] Final Memory: 16M/39M
[INFO] ------------------------------------------------------------------------
My goal was to resolve all of the warning messages that had cropped up in the [...]</description>
			<content:encoded><![CDATA[<p>Well, it took a little longer than I care to admit, but I finally got back to here:</p>
<pre>[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESSFUL
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1 minute 41 seconds
[INFO] Finished at: Tue Dec 02 18:41:45 PST 2008
[INFO] Final Memory: 16M/39M
[INFO] ------------------------------------------------------------------------</pre>
<p>My goal was to resolve all of the warning messages that had cropped up in the core project once I changed the Java version to 5.0, but I have to admit that after a while I got a little lazy and just slipped in the old <strong>@SuppressWarnings(&#8221;unchecked&#8221;)</strong> in more places than are really appropriate, just to speed up my journey to &#8220;done&#8221;. Also, it didn&#8217;t help that I had stubbed out the <em>findByTableIdEntryId</em> method (&#8221;return null;&#8221;) in the <a title="DAO Refactoring: Lookup Table DAOs" href="http://blog.restafarian.org/2008/11/dao-refactoring-lookup-table-daos/" target="_self">LookupTableEntryDaoHibernate</a> the other day and forgot to go back and actually put in the code to return valid results. That had me running around in circles for a while trying to figure out why the <em>testFindByTableIdEntryId</em> kept returning nothing when I knew damn well that there was data in the database, but eventually I managed to figure that out.</p>
<p>So, that takes care of one my many little interrelated projects &#8230; now I just have to go through all of the others and do the same thing!</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Restafarianorg?a=1qCoO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=1qCoO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=EBBEO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=EBBEO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=D86YO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=D86YO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=3hdXO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=3hdXO" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=2MhTO"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=2MhTO" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Restafarianorg/~4/473156963" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.restafarian.org/2008/12/dao-refactoring-finally/feed/</wfw:commentRss>
		<feedburner:origLink>http://blog.restafarian.org/2008/12/dao-refactoring-finally/</feedburner:origLink></item>
		<item>
		<title>DAO Refactoring: Lookup Table DAOs</title>
		<link>http://feeds.feedburner.com/~r/Restafarianorg/~3/470491924/</link>
		<comments>http://blog.restafarian.org/2008/11/dao-refactoring-lookup-table-daos/#comments</comments>
		<pubDate>Sun, 30 Nov 2008 18:35:59 +0000</pubDate>
		<dc:creator>Restamon</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[dao]]></category>

		<category><![CDATA[dao refactoring]]></category>

		<category><![CDATA[Hibernate]]></category>

		<category><![CDATA[look-up tables]]></category>

		<category><![CDATA[refactoring]]></category>

		<category><![CDATA[spring]]></category>

		<guid isPermaLink="false">http://blog.restafarian.org/?p=364</guid>
		<description>Since I decided to go with this version, I went ahead and went all the way back to the Look-up Table project and reworked these into this:
package org.restafarian.core.dao.hibernate;

import org.hibernate.SessionFactory;
import org.restafarian.core.beans.LookupTable;
import org.restafarian.core.dao.LookupTableDao;

/**
 * &amp;#60;p&amp;#62;This is the LookupTable data access object.&amp;#60;/p&amp;#62;
 */
public class LookupTableDaoHibernate extends AbstractHibernateDao&amp;#60;LookupTable&amp;#62;
       implements LookupTableDao {

  /**
 [...]</description>
			<content:encoded><![CDATA[<p>Since I decided to go with <a title="DAO Refactoring: One more version" href="http://blog.restafarian.org/2008/11/dao-refactoring-one-more-version/">this version</a>, I went ahead and went all the way back to the <a title="Next Up: Universal look-up tables" href="http://blog.restafarian.org/2008/06/next-up-universal-look-up-tables/" target="_self">Look-up Table project</a> and reworked <a title="Look-up Tables: DAO components" href="http://blog.restafarian.org/2008/07/look-up-tables-dao-components/" target="_self">these</a> into this:</p>
<pre>package org.restafarian.core.dao.hibernate;

import org.hibernate.SessionFactory;
import org.restafarian.core.beans.LookupTable;
import org.restafarian.core.dao.LookupTableDao;

/**
 * &lt;p&gt;This is the LookupTable data access object.&lt;/p&gt;
 */
public class LookupTableDaoHibernate extends AbstractHibernateDao&lt;LookupTable&gt;
       implements LookupTableDao {

  /**
   * &lt;p&gt;Constructs a new LookupTableDaoHibernate using the parameters provided.&lt;/p&gt;
   */
  public LookupTableDaoHibernate(SessionFactory sessionFactory) {
    super(LookupTable.class, sessionFactory);
  }
}</pre>
<p>&#8230; and this:</p>
<pre>package org.restafarian.core.dao.hibernate;

import org.hibernate.SessionFactory;
import org.restafarian.core.beans.LookupTableEntry;
import org.restafarian.core.dao.LookupTableEntryDao;

/**
 * &lt;p&gt;This is the LookupTableEntry data access object.&lt;/p&gt;
 */
public class LookupTableEntryDaoHibernate extends AbstractHibernateDao&lt;LookupTableEntry&gt;
       implements LookupTableEntryDao {

  /**
   * &lt;p&gt;Constructs a new LookupTableEntryDaoHibernate using the parameters provided.&lt;/p&gt;
   */
  public LookupTableEntryDaoHibernate(SessionFactory sessionFactory) {
    super(LookupTableEntry.class, sessionFactory);
  }

  /**
   * &lt;p&gt;Returns the LookupTableEntry with the specified table id
   * and entry id.&lt;/p&gt;
   *
   * @param id the id of the requested look-up table
   * @param id the id of the requested entry
   * @return the requested LookupTableEntry
   */
  public LookupTableEntry findByTableIdEntryId(String tableId, String entryId) {
    return null;
  }
}</pre>
<p>Much smaller than the originals, which I like, but since I changed the interface just a tad, I now have to go back and rework the service layer and the unit tests to sync everything back up.</p>
<p><a title="http://raykrueger.blogspot.com/" href="http://raykrueger.blogspot.com/" target="_blank">Good Mr. Krueger</a> has also provided <a title="DAO Refactoring: One more version" href="http://blog.restafarian.org/2008/11/dao-refactoring-one-more-version/" target="_self">some even more useful suggestions</a>, so I&#8217;ll be taking a look at those as well. I had originally thought about dumping the old <em>.hbm.xml</em> files in favor of annotations back when I started this refactoring process, which I still intend to do, but I wanted to limit myself to just one set of new things at a time while I worked my way through the DAO enhancements. With these other suggestions, now may be a good point to go back yet again, and make the move to annotations at the same time.</p>
<p>But first I think I have a little work to do with all of the rest of my little parts and pieces now that I have brought a couple of the projects in the pile up to Java 5 and left the rest behind. I think I better work on bringing everything else in the portfolio up-level as well, and then see if I can make my way through a full build! That may take a little time &#8230;</p>
<div class="feedflare">
<a href="http://feeds.feedburner.com/~f/Restafarianorg?a=iuJcN"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=iuJcN" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=AcqLN"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=AcqLN" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=B3gfN"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=B3gfN" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=SvObN"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=SvObN" border="0"></img></a> <a href="http://feeds.feedburner.com/~f/Restafarianorg?a=SQBmN"><img src="http://feeds.feedburner.com/~f/Restafarianorg?i=SQBmN" border="0"></img></a>
</div><img src="http://feeds.feedburner.com/~r/Restafarianorg/~4/470491924" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.restafarian.org/2008/11/dao-refactoring-lookup-table-daos/feed/</wfw:commentRss>
		<feedburner:origLink>http://blog.restafarian.org/2008/11/dao-refactoring-lookup-table-daos/</feedburner:origLink></item>
	</channel>
</rss>
