<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Matt Stine&#039;s Blog &#187; groovy</title>
	<atom:link href="http://mattstine.com/category/groovy/feed/" rel="self" type="application/rss+xml" />
	<link>http://mattstine.com</link>
	<description>Thoughts on Java, Groovy, Grails, Agile Development, etc. etc. etc.</description>
	<lastBuildDate>Tue, 17 May 2011 17:02:53 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='mattstine.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://s2.wp.com/i/buttonw-com.png</url>
		<title>Matt Stine&#039;s Blog &#187; groovy</title>
		<link>http://mattstine.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://mattstine.com/osd.xml" title="Matt Stine&#039;s Blog" />
	<atom:link rel='hub' href='http://mattstine.com/?pushpress=hub'/>
		<item>
		<title>Securing Grails Plugin Artifacts with Filters</title>
		<link>http://mattstine.com/2009/11/10/securing-grails-plugin-artifacts-with-filters/</link>
		<comments>http://mattstine.com/2009/11/10/securing-grails-plugin-artifacts-with-filters/#comments</comments>
		<pubDate>Tue, 10 Nov 2009 18:50:11 +0000</pubDate>
		<dc:creator>mattstine</dc:creator>
				<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://www.mattstine.com/?p=278</guid>
		<description><![CDATA[So you&#8217;ve just installed the handy dandy Spring Security plugin (http://grails.org/plugin/acegi), which makes it incredibly easy to secure entire Grails controllers and/or controller actions with annotations, such as the following: This is enabled by turning on controller annotations in your SecurityConfig.groovy file: So all is now good in our project. We can secure either controllers [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=278&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>So you&#8217;ve just installed the handy dandy Spring Security plugin (http://grails.org/plugin/acegi), which makes it incredibly easy to secure entire Grails controllers and/or controller actions with annotations, such as the following:</p>
<p>This is enabled by turning on controller annotations in your SecurityConfig.groovy file:</p>
<p>So all is now good in our project. We can secure either controllers or actions with annotations, enabling us to declaratively setup security side-by-side with the code that we&#8217;re securing in a very straightforward manner. You can continue developing your Grails applications with glee, fully assured that security is no longer an issue. But wait, one day you decide to install one of the many useful Grails plugins that add controller artifacts to your application. Lo and behold, you have no way to secure those controllers! Of course, you could descend into $USER_HOME/.grails/$GRAILS_VERSION/projects/projectName/plugins/pluginX and hack the source code for your individual instance of the plugin. This ought to work, but you&#8217;re now rather constrained in that every time you update the plugin you&#8217;ll need to remember to go make this manual change. That doesn&#8217;t sound very agile at all, does it? OK, so how about forking the plugin? This is a little bit better, but now you have the burden of merging changes from the global plugin repository to yours every time a new release happens. This is better, but still a bit cumbersome. How about becoming a committer and adding it to the global source? Of course not. Not everyone will want to secure their plugins the same way you do, and you&#8217;ve just introduced a rather unnecessary dependency on the Spring Security plugin. I say all this in an attempt to paint a grim picture. In reality, we&#8217;re actually in very good shape. Grails Filters to the rescue!</p>
<p>All that you need to do is create a Grails filter that will match requests to the plugin artifact in question and then delegate to Spring Security for authorization. If they are authorized, you simply return true. If not, you can direct them to your login screen. It&#8217;s this simple:</p>
<p>As you can see here, I&#8217;ve secured both the Blurb plugin and the Settings plugin in this manner by requiring that the logged in user be in the ROLE_ADMIN role. Now as Glen Smith would say, that&#8217;s a snack!</p>
<p><em><strong>Update:</strong> <a href="http://burtbeckwith.com/blog/">Burt Beckwith</a> enlightened me to an approach that will get this done without the use of filters that will also direct you to the requested URL after login rather than the main page. Unfortunately I&#8217;ve never been able to track this down before. Just add the following to SecurityConfig.groovy:</em></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattstine.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattstine.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mattstine.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mattstine.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mattstine.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mattstine.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mattstine.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mattstine.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mattstine.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mattstine.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mattstine.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mattstine.wordpress.com/278/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mattstine.wordpress.com/278/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mattstine.wordpress.com/278/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=278&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattstine.com/2009/11/10/securing-grails-plugin-artifacts-with-filters/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1eaa45fee6a2b0c4b479b2982a4274f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mattstine</media:title>
		</media:content>
	</item>
		<item>
		<title>Making Java &#8220;Groovier&#8221; with LambdaJ</title>
		<link>http://mattstine.com/2009/10/09/making-java-groovier-with-lambdaj/</link>
		<comments>http://mattstine.com/2009/10/09/making-java-groovier-with-lambdaj/#comments</comments>
		<pubDate>Fri, 09 Oct 2009 14:37:06 +0000</pubDate>
		<dc:creator>mattstine</dc:creator>
				<category><![CDATA[functional-programming]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[loty]]></category>

		<guid isPermaLink="false">http://www.mattstine.com/?p=257</guid>
		<description><![CDATA[I spent the better part of yesterday tracing my way through the codebase for a large-scale enterprise application that my team is building right now, and I happened upon the following piece of code: As I read this code, I thought &#8220;This just SCREAMS a need for Groovy&#8217;s closure iterators.&#8221; So, last night I quickly [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=257&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I spent the better part of yesterday tracing my way through the codebase for a large-scale enterprise application that my team is building right now, and I happened upon the following piece of code:</p>
<p><pre class="brush: java;">
//...imports excluded for clarity
public class BusinessActivityBinMetaClassHelper {
//...
   public static List&lt;Long&gt; getSrmMetaClassIdListJava(List&lt;BusinessActivityBinMetaClass&gt; businessActivityBinMetaClassList) {
      List&lt;Long&gt; srmMetaClassIdList = new ArrayList&lt;Long?();

      if(businessActivityBinMetaClassList != null) {
         for(BusinessActivityBinMetaClass businessActivityBinMetaClass : businessActivityBinMetaClassList) {
             if(businessActivityBinMetaClass.getSrmMetaClass() != null &amp;&amp; businessActivityBinMetaClass.getSrmMetaClass().getSrmMetaClassId() != null) {
               srmMetaClassIdList.add
                  (businessActivityBinMetaClass.getSrmMetaClass().getSrmMetaClassId());
            }
         }
      }

      return srmMetaClassIdList;
   }
//...
}
</pre></p>
<p>As I read this code, I thought &#8220;This just SCREAMS a need for Groovy&#8217;s closure iterators.&#8221; So, last night I quickly hacked out fully-equivalent Groovy version of the code:</p>
<p><pre class="brush: groovy;">
class GroovyExample {

   static def getSrmMetaClassIdListGroovy(def businessActivityBinMetaClassList) {
      businessActivityBinMetaClassList?.collect { it?.srmMetaClass?.srmMetaClassId }.findAll { it != null } ?: new ArrayList&lt;Long&gt;();
   }
}
</pre></p>
<p>Whew! Much nicer. What did we get out of this? Well&#8230;</p>
<ul>
<li>Groovy&#8217;s dynamic typing cleaned up all of the unnecessary type declarations &#8211; the only static typing is where we return an empty ArrayList of Longs if the argument to our method is null (a bit of odd behavior, but required to make this code equivalent to the parent Java code.</li>
<li>We were saved 4 painful null checks by the use of Groovy&#8217;s null safe dereferencing operator (?.) and the simplified ternary operator otherwise affectionately known as the &#8220;Elvis Operator&#8221; (?:).</li>
<li>Using Groovy&#8217;s collect method, we were able to transform the original list into a list containing Long values by passing in a closure that pulls out the property value of interest.</li>
<li>Because we&#8217;re using null safe dereferencing, we are actually inserting nulls into our list if any of the dereferencing fails. Therefore, Groovy&#8217;s findAll Collection filtering method comes to the rescue. We simply provide it with a closure that returns true for all of the values we want to keep &#8211; in this case, &#8220;it != null.&#8221;</li>
<li>Perhaps most importantly, we&#8217;ve shorted our code from 11 lines (including whitespace lines for clarity) to ONE LINE that much more clearly expresses the intent of the code.</li>
</ul>
<p>Great &#8211; why don&#8217;t we just rewrite the entire application is Groovy? Well, hold on just a minute. At the time we started this application, as much as some of us loved Groovy, we just didn&#8217;t have enough Groovy mindshare to go there yet. On top of that, we were already experimenting with several new architectural ideas and technologies, and Groovy would have added yet one more risk to the puzzle. I say all this to acknowledge that sometimes you just can&#8217;t move to another language for one reason or another, regardless of how attractive its features may be.</p>
<p>But let&#8217;s take a queue from the <em>Pragmatic Programmer</em> and explore the LOTY (Language of the Year) concept one more time. One of the reasons that you&#8217;re encouraged to learn new languages is to change the way you program in your main language. You may learn Groovy, Scala, Clojure, Ruby, etc., etc., etc. and never use them in your day job &#8211; and yet the experience of coding in a new language with new constructs and idioms will necessarily change the way you THINK about programming in every other language.</p>
<p>So, let&#8217;s think about the possibility of coding something that is much more similar to the Groovy version and yet stick with regular Java code. Fortunately, there are several libraries out there that bring much of the flavor and power of Groovy&#8217;s closure iterators to Java. I&#8217;d like to focus in on one of them, LambdaJ (<a href="http://code.google.com/p/lambdaj/">http://code.google.com/p/lambdaj/</a>).</p>
<p>LambdaJ provides constructs that allow us to &#8220;&#8230;manipulate collections in a pseudo-functional and statically typed way.&#8221; Let&#8217;s take a look at this example implementing using LambdaJ:</p>
<p><pre class="brush: java;">
//...some imports excluded for clarity
import ch.lambdaj.function.convert.Converter
import static ch.lambdaj.Lambda.*
import static org.hamcrest.Matchers.*

public class BusinessActivityBinMetaClassHelper {
//...
   public static List&lt;Long&gt; getSrmMetaClassIdListJava(List&lt;BusinessActivityBinMetaClass&gt; businessActivityBinMetaClassList) {
      return (businessActivityBinMetaClassList != null) ? filter(notNullValue(),convert(businessActivityBinMetaClassList, new IdExtractor())) : new ArrayList&lt;Long&gt;();
   }

   class IdExtractor implements Converter&lt;BusinessActivityBinMetaClass,Long&gt; {
	Long convert(BusinessActivityBinMetaClass from) {
	   if (from.getSrmMetaClass() != null &amp;&amp; from.getSrmMetaClass().getSrmMetaClassId() != null) {
	      return from.getSrmMetaClass().getSrmMetaClassId();
	   }
   }
}
</pre></p>
<p>Not quite as nice as the Groovy code &#8211; we got A LOT out of the null-safe dereference and Elvis operators. However, our overall intent is still a bit clearer. Let&#8217;s analyze:</p>
<ul>
<li>First we need to implement one of LambdaJ&#8217;s Converters. A Converter is nothing more than a generic Interface that defines one method: T convert(F from), where F is the type we&#8217;re converting from and T is the type we&#8217;re converting to. In this case, we want to convert an object of type BusinessActivityBinMetaClass to an object of type Long. Our implementation determines how this conversion takes place, in this case by extracting the id property from its child.</li>
<li>Next, after statically importing the methods of ch.lambdaj.Lambda, we call the convert method, passing it our List and our newly implemented Converter. This gives us the equivalent of Groovy&#8217;s collect method, with the Converter taking the place of the closure.</li>
<li>We&#8217;re still shoving nulls into our List with this implementation, so we further filter our list using LambdaJ&#8217;s &#8220;filter&#8221; method, passing it the list returned by &#8220;filter,&#8221; and a <a href="http://code.google.com/p/hamcrest/">Hamcrest</a> matcher that returns only notNullValue()&#8217;s.</li>
<li>Finally, we use our old friend the ternary operator to return the empty ArrayList of Long values if our method argument is null.</li>
</ul>
<p>If you don&#8217;t count the Converter implementation, we&#8217;ve gotten ourselves down to 2 lines of code (1 if you don&#8217;t mind long lines). In this case I implemented IdExtractor as a named inner class &#8211; you could do this with an anonymous inner class and it would look a lot more like a closure, but the added noise of all of the null checking made the undesirable for me. Perhaps if your code has less noise (or guarantees that values aren&#8217;t null), that would be a better approach.</p>
<p>Another alternative is to make IdExtractor a top-level class that, if general enough, could be reused throughout the codebase. The benefit of this is that you now have a nice code unit rather than a battery of static methods in a utility class, and unit testing becomes much more clean and elegant.</p>
<p>So, we&#8217;ve still made some progress and made our code a bit more Groovy. I encourage you to explore LambdaJ&#8217;s feature set and see how it might make your code a bit more concise with clearer intent. And just to stir up a little controversy, look what would have happened in Java 7 had the null safe dereference and Elvis operator&#8217;s made <a href="http://blogs.sun.com/darcy/entry/project_coin_final_five">the Project Coin cut</a>:</p>
<p><pre class="brush: java;">
//...some imports excluded for clarity
import ch.lambdaj.function.convert.Converter
import static ch.lambdaj.Lambda.*
import static org.hamcrest.Matchers.*

public class BusinessActivityBinMetaClassHelper {
//...
   public static List&lt;Long&gt; getSrmMetaClassIdListLambdaJ(List&lt;BusinessActivityBinMetaClass&gt; businessActivityBinMetaClassList) {
      return filter(notNullValue(),convert(businessActivityBinMetaClassList,
         new Converter&lt;BusinessActivityBinMetaClass,Long&gt; {
            Long apply(BusinessActivityBinMetaClass from) { return from?.getSrmMetaClass()?.getSrmMetaClassId()}
         })) ?: new ArrayList&lt;Long&gt;();
   }
}
</pre></p>
<p>Nice, huh? <img src='http://s1.wp.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattstine.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattstine.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mattstine.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mattstine.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mattstine.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mattstine.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mattstine.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mattstine.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mattstine.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mattstine.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mattstine.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mattstine.wordpress.com/257/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mattstine.wordpress.com/257/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mattstine.wordpress.com/257/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=257&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattstine.com/2009/10/09/making-java-groovier-with-lambdaj/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1eaa45fee6a2b0c4b479b2982a4274f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mattstine</media:title>
		</media:content>
	</item>
		<item>
		<title>I&#8217;ve &#8220;forked&#8221; the Grails PayPal Plugin&#8230;</title>
		<link>http://mattstine.com/2009/05/02/ive-forked-the-grails-paypal-plugin/</link>
		<comments>http://mattstine.com/2009/05/02/ive-forked-the-grails-paypal-plugin/#comments</comments>
		<pubDate>Sat, 02 May 2009 05:59:46 +0000</pubDate>
		<dc:creator>mattstine</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://www.mattstine.com/?p=158</guid>
		<description><![CDATA[I&#8217;m currently completing the finishing touches on a new e-commerce site for my wife&#8217;s stationary business. We decided a long time ago to use PayPal for all of the payment processing since we&#8217;ve had a great experience using it for our eBay selling. About a year ago Graeme Rocher polished off the last release of [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=158&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m currently completing the finishing touches on a new e-commerce site for my wife&#8217;s stationary business. We decided a long time ago to use <a href="http://www.paypal.com">PayPal</a> for all of the payment processing since we&#8217;ve had a great experience using it for our eBay selling. About a year ago Graeme Rocher polished off the last release of a <a href="http://grails.org/plugin/paypal">PayPal plugin</a> that is available in <a href="http://grails.org/plugin/home">the Grails Plugin repository</a>. It really is a very nice plugin, yet I had a couple of problems with it:</p>
<ul>
<li>It is only capable of handling payments for one item transactions via &#8220;Buy Now&#8221; buttons. I want to upload an entire shopping cart full of multiple items.</li>
<li>It currently won&#8217;t handle shipping addresses. The site I&#8217;m building allows the user to maintain a list of shipping addresses, and I&#8217;d want to send the address information they choose along to PayPal.</li>
<li>Minor issue: needed to upgrade the plugin to Grails 1.1.</li>
</ul>
<p>So, I decided this evening to fork the plugin. I want to leverage all of the great work that has been done thus far (especially with the IPN processing part &#8211; superb stuff), but I have to add in these two functions and do the version upgrade. Interestingly enough I couldn&#8217;t get the tests to run out of the box after the upgrade. No good developer likes to modify code without a stable running test suite, right? So what I ended up doing was creating a new Grails 1.1 plugin project and copying the original artifacts over. Once this was done all of the tests ran perfectly.</p>
<p>So, at this point I&#8217;ve added function #1. You can now redirect to the &#8220;uploadCart&#8221; action. It assumes that you have already constructed a Payment object (now containing PaymentItems) and saved it, and then passed the transactionId along. I did this so that folks with multiple different ways of handling shopping carts could have some degree of flexibility &#8211; the onus is on you to map your cart to your Payment object correctly. The original functions implemented by Graeme are backward compatible, assuming only one PaymentItem in the Payment. I&#8217;ve run all of the original tests and also did some manual functional testing by running the plugin app against my own PayPal Sandbox account. So far so good. Look for more updates as this evolves. Once I get something I&#8217;m totally happy with I&#8217;ll see about getting it pushed back into the main plugin repo.</p>
<p>Want to take a closer look? Visit <a href="http://github.com/mstine/grails-paypal-plugin/tree/master">http://github.com/mstine/grails-paypal-plugin/tree/master</a></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattstine.wordpress.com/158/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattstine.wordpress.com/158/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mattstine.wordpress.com/158/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mattstine.wordpress.com/158/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mattstine.wordpress.com/158/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mattstine.wordpress.com/158/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mattstine.wordpress.com/158/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mattstine.wordpress.com/158/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mattstine.wordpress.com/158/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mattstine.wordpress.com/158/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mattstine.wordpress.com/158/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mattstine.wordpress.com/158/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mattstine.wordpress.com/158/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mattstine.wordpress.com/158/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=158&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattstine.com/2009/05/02/ive-forked-the-grails-paypal-plugin/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1eaa45fee6a2b0c4b479b2982a4274f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mattstine</media:title>
		</media:content>
	</item>
		<item>
		<title>Joel&#8217;s BuilderBuilder in Groovy</title>
		<link>http://mattstine.com/2009/04/27/joels-builderbuilder-in-groovy/</link>
		<comments>http://mattstine.com/2009/04/27/joels-builderbuilder-in-groovy/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 02:54:07 +0000</pubDate>
		<dc:creator>mattstine</dc:creator>
				<category><![CDATA[functional-programming]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://www.mattstine.com/?p=149</guid>
		<description><![CDATA[Joel Neely started a series of posts over the weekend detailing a proposed exploration of what Functional Programming means &#8220;to me as a practicing OO software developer?&#8221; The task at hand is to look at the generation of Data Transfer Objects which include a static inner class that functions as a builder. Since I&#8217;m exploring [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=149&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://joelneely.wordpress.com/">Joel Neely</a> started <a href="http://joelneely.wordpress.com/2009/04/25/builderbuilder-the-agenda/">a series</a> <a href="http://joelneely.wordpress.com/2009/04/27/builderbuilder-the-task/">of posts</a> over the weekend detailing a proposed exploration of what Functional Programming means &#8220;to me as a practicing OO software developer?&#8221; The task at hand is to look at the generation of Data Transfer Objects which include a static inner class that functions as a builder. Since I&#8217;m exploring both Clojure and Scala right now, Joel has asked me to play along.</p>
<p>After reading the task definition today, I couldn&#8217;t resist taking a crack at the problem in Groovy, especially since tackling a Builder DSL is not something I&#8217;ve gone after before.</p>
<p>So, here&#8217;s how I&#8217;ll use my DTOBuilder to produce the output Joel described:</p>
<pre class="brush: groovy">
def bldr = new DtoBuilder()

println bldr.build {
	packageName 'edu.bogusu.registration'
	name 'Student'
	field(name:'id', type:'String')
	field(name:'firstName', type:'String')
	field(name:'lastName', type:'String')
	field(name:'hoursEarned', type:'int')
	field(name:'gpa', type:'float')
}
</pre>
<p>Pretty concise, eh? <a href="http://github.com/mstine/BuilderBuilder/blob/1008235f88177910eb94af165ade3aedae2955a3/src/DtoBuilder.groovy">Check out the implementation of it at GitHub</a>. I&#8217;ll be posting all of my code related to this series at this location (and hopefully Joel will join in as well).</p>
<p>One thing you&#8217;ll notice is that I&#8217;m still operating primarily in OO style. My next task is to refactor this code, still written in Groovy, but using as much functional-style as I can squeeze out of the language. Until next time&#8230;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattstine.wordpress.com/149/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattstine.wordpress.com/149/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mattstine.wordpress.com/149/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mattstine.wordpress.com/149/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mattstine.wordpress.com/149/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mattstine.wordpress.com/149/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mattstine.wordpress.com/149/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mattstine.wordpress.com/149/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mattstine.wordpress.com/149/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mattstine.wordpress.com/149/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mattstine.wordpress.com/149/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mattstine.wordpress.com/149/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mattstine.wordpress.com/149/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mattstine.wordpress.com/149/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=149&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattstine.com/2009/04/27/joels-builderbuilder-in-groovy/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1eaa45fee6a2b0c4b479b2982a4274f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mattstine</media:title>
		</media:content>
	</item>
		<item>
		<title>Groovy: Post to a URL</title>
		<link>http://mattstine.com/2009/04/25/groovy-post-to-a-url/</link>
		<comments>http://mattstine.com/2009/04/25/groovy-post-to-a-url/#comments</comments>
		<pubDate>Sun, 26 Apr 2009 04:09:11 +0000</pubDate>
		<dc:creator>mattstine</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://www.mattstine.com/?p=146</guid>
		<description><![CDATA[If you&#8217;ve ever worked with the brilliant Recaptcha service, you&#8217;ll know that their REST API requires an HTTP POST rather than a GET. As I had only used GET requests thus far, I googled around and found a pretty easy solution: private def evaluateCaptcha(def remoteIp, def challenge, def response) { def config = recaptchaService.getRecaptchaConfig() def [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=146&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve ever worked with the brilliant <a href="http://recaptcha.net/">Recaptcha</a> service, you&#8217;ll know that their REST API requires an HTTP POST rather than a GET. As I had only used GET requests thus far, I googled around and found a pretty easy solution:</p>
<pre class="brush: groovy">
private def evaluateCaptcha(def remoteIp, def challenge, def response) {
    def config = recaptchaService.getRecaptchaConfig()

    def urlString = "http://api-verify.recaptcha.net/verify"
    def queryString = "privatekey=${config.recaptcha.privateKey}&amp;remoteip=${remoteIp}&amp;challenge=${challenge}&amp;response=${URLEncoder.encode(response)}"

    def url = new URL(urlString)
    def connection = url.openConnection()
    connection.setRequestMethod("POST")
    connection.doOutput = true

    def writer = new OutputStreamWriter(connection.outputStream)
    writer.write(queryString)
    writer.flush()
    writer.close()
    connection.connect()

    def recaptchaResponse = connection.content.text
    log.debug(recaptchaResponse)

    recaptchaResponse.startsWith("true")
}
</pre>
<p>I have to credit <a href="http://www.fiascode.com/programming/putting-google-finance-to-rest-with-groovy/">Justin Spradlin</a> for the code that ultimately got me here. Consider this a +1.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattstine.wordpress.com/146/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattstine.wordpress.com/146/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mattstine.wordpress.com/146/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mattstine.wordpress.com/146/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mattstine.wordpress.com/146/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mattstine.wordpress.com/146/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mattstine.wordpress.com/146/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mattstine.wordpress.com/146/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mattstine.wordpress.com/146/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mattstine.wordpress.com/146/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mattstine.wordpress.com/146/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mattstine.wordpress.com/146/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mattstine.wordpress.com/146/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mattstine.wordpress.com/146/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=146&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattstine.com/2009/04/25/groovy-post-to-a-url/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1eaa45fee6a2b0c4b479b2982a4274f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mattstine</media:title>
		</media:content>
	</item>
		<item>
		<title>Grails, Prototype, Script.aculo.us &#8211; Persistent Grid Sorting Goodness</title>
		<link>http://mattstine.com/2009/04/25/grails-prototype-scriptaculous-persistent-grid-sorting-goodness/</link>
		<comments>http://mattstine.com/2009/04/25/grails-prototype-scriptaculous-persistent-grid-sorting-goodness/#comments</comments>
		<pubDate>Sat, 25 Apr 2009 05:14:40 +0000</pubDate>
		<dc:creator>mattstine</dc:creator>
				<category><![CDATA[ajax]]></category>
		<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[prototype]]></category>
		<category><![CDATA[scriptaculous]]></category>

		<guid isPermaLink="false">http://www.mattstine.com/?p=139</guid>
		<description><![CDATA[Ever wanted to do drag-n-drop sorting of a grid of images on a page and persist it? Here&#8217;s my solution using Grails, Prototype, and Script.aculo.us. Basically what prompted this was the need for my wife to be able to sort the various product images that she had on a screen at any given time in [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=139&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Ever wanted to do drag-n-drop sorting of a grid of images on a page and persist it? Here&#8217;s my solution using Grails, Prototype, and Script.aculo.us.</p>
<p>Basically what prompted this was the need for my wife to be able to sort the various product images that she had on a screen at any given time in any way that she pleased, and it had to be easy to work with. What follows is by no means a complete solution to this problem, but it represents where I am in the development process and may be useful to you, my hapless reader.</p>
<p>Here&#8217;s some GSP code which basically lays out a grid of product images, 3 wide by <em>n</em> deep:</p>
<pre class="brush: xml">
&lt;div id="productThumbContainer"&gt;
  &lt;g:set var="rowIndex" value="${0}"/&gt;
&lt;g:each in="${products}" var="product" status="index"&gt;
  &lt;g:if test="${index % 3 == 0}"&gt;
    &lt;div id="productRow${rowIndex}" class="span-20 last product-row"&gt;
  &lt;/g:if&gt;
  &lt;div id="product_${product.id}" class="span-6 product &lt;g:if test="${(index % 3 == 2) || ((products.size() - index) == 1)}"&gt;last&lt;/g:if&gt;&lt;g:else&gt;append-1&lt;/g:else&gt;"&gt;
    &lt;img src="${resource(dir: grailsApplication.config.store.productImages.webPath, file: product?.thumbnailImage?.name)}" width="230" class="productImage"&gt;
    &lt;h3&gt;&lt;g:link controller="product" action="show" id="${product.id}"&gt;${product.name}&lt;/g:link&gt;&lt;/h3&gt;
  &lt;/div&gt;
  &lt;g:if test="${(index % 3 == 2) || ((products.size() - index) == 1)}"&gt;
    &lt;/div&gt;
    &lt;g:set var="rowIndex" value="${rowIndex + 1}"/&gt;
  &lt;/g:if&gt;
&lt;/g:each&gt;
&lt;/div&gt;
</pre>
<p>Now here&#8217;s where the magic happens:</p>
<pre class="brush: js">
document.observe('dom:loaded', function() {
      var productRows = $$('.product-row');

      var options = {
        constraint: false,
        overlap: 'horizontal',
        containment: productRows,
        dropOnEmpty: true,
        tag: 'div',
        onUpdate: updateRows
      };

      productRows.each(function(item) {
        Sortable.create(item, options);
      });

      $('persistOrderingButton').observe('click', function(event) {
          var sortString = '';
          productRows.each(function(row) {
              sortString += '&amp;';
              sortString += Sortable.serialize(row);
          });
          &lt;g:remoteFunction action="sortProducts" params="sortString" update="ajaxMessage" onSuccess="\$('ajaxMessage').show()"/&gt;
      });
});
</pre>
<p>What we&#8217;ve got here is, failure to communicate&#8230;oops, wrong synapse there&#8230;what we&#8217;ve got here is a Prototype selector that grabs everything with the class &#8220;.product-row.&#8221; It then takes these and creates a Scriptaculous Sortable for each of them, providing the object-literal &#8220;options.&#8221; Notice the &#8220;containment&#8221; option which allows you to drag products back and forth between the various rows.</p>
<p>Delving deeper into the magic is the callback function &#8220;updateRows.&#8221; This guy is my favorite Javascript creation in quite some time:</p>
<pre class="brush: js">
function updateRows(list) {
      var children = list.childElements();

      if (children.size() &lt; 3) {

        //If I&#039;m the last row, who cares!
        if (list.next() != null) {
          var prevRow = list.previous();

          if (prevRow != null) {
            var lastChild = prevRow.childElements()[prevRow.childElements().size() - 1].remove();
            list.insert({top:lastChild});
            updateRows(prevRow);
          } else {
            var lastRow = list.up().childElements()[list.up().childElements().size() - 1];
            var lastChild = lastRow.childElements()[lastRow.childElements().size() - 1].remove();
            list.insert({top:lastChild});
            updateRows(lastRow);
          }
        }
      } else if (children.size() == 3) {
        //Do nothing...gets me out of the recursion I hope!
      } else {
        var nextRow = list.next();
        var lastChild = children[children.size() - 1].remove();

        if (nextRow != null) {
          nextRow.insert({top:lastChild});
          updateRows(nextRow);
        } else {
          var topRow = list.up().childElements()[0];
          topRow.insert({top:lastChild});
          updateRows(topRow);
        }
      }

      var i = 0;
      Sortable.sequence(list).each(function(item) {
        var productId = &#039;product_&#039; + item;
        if (i &lt; 2) {
          $(productId).removeClassName(&#039;last&#039;);
          $(productId).removeClassName(&#039;append-1&#039;);
          $(productId).addClassName(&#039;append-1&#039;);
        } else {
          $(productId).removeClassName(&#039;last&#039;);
          $(productId).removeClassName(&#039;append-1&#039;);
          $(productId).addClassName(&#039;last&#039;);
        }
        i++;
      });
}
</pre>
<p>This function is organized around the fact that the only valid state for a grid of n-rows will be n-1 rows of 3 products, followed by one row of 1 &lt;= numProducts &lt;= 3. In most cases, if you drag a product from one row to another, you are violating that rule by creating a row with 2 products and a row with 4 products. This function solves the problem by recursively shifting the products down until reaching a stable state again.</p>
<p>There&#039;s a bit of noise there at the bottom of the function. I&#039;m using Blueprint CSS to do the layout for this application and I need to shift the various Blueprint classes around once everything is settled.</p>
<p>Finally, here&#039;s the persistence of the data when we click save:</p>
<pre class="brush: groovy">
def sortProducts = {
    TreeMap rowMap = new TreeMap()

    params.each {key, value -&gt;
      def matcher = key =~ /productRow(.*)\[\]/
      if (matcher.matches()) {
        def rowId = matcher[0][1]
        rowMap[rowId] = value
      }
    }

    def productIds = []
    rowMap.values().each { row -&gt;
      row.each {
        productIds &lt;&lt; it.toLong()
      }
    }

    shoppingService.saveSortOrder(productIds)

    render(&quot;Product sort order saved!&quot;)
}
</pre>
<p>and the logic from shoppingService.saveSortOrder():</p>
<pre class="brush: groovy">
def saveSortOrder(def productIds) {
    def productsToSort = Product.findAllByIdInList(productIds)

    def productMap = [:]
    def sortIndexList = []

    productsToSort.each {
      productMap[it.id] = it
      sortIndexList &lt;&lt; it.sortIndex
    }

    sortIndexList.sort()
    sortIndexList = sortIndexList.reverse()

    productIds.each {
      productMap[it].sortIndex = sortIndexList.pop()
    }

    productsToSort.each {
      it.save()
    }
}
</pre>
<p>You might wonder why this is so complex. What I haven&#8217;t fully described is the way products are organized into a hierarchy of various categories. When you&#8217;re sorting a screen, you&#8217;re only sorting a subset of the products that are in that particular category. However, the sort order is maintained across the entire product set in the database. So, this logic basically just shifts around the existing sort indicies, placing them in their new relative order.</p>
<p>Anyway, I don&#8217;t know how generally applicable this code is, but I had fun writing it and I hope you can get some use out of it. Cheers!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattstine.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattstine.wordpress.com/139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mattstine.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mattstine.wordpress.com/139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mattstine.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mattstine.wordpress.com/139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mattstine.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mattstine.wordpress.com/139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mattstine.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mattstine.wordpress.com/139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mattstine.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mattstine.wordpress.com/139/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mattstine.wordpress.com/139/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mattstine.wordpress.com/139/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=139&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattstine.com/2009/04/25/grails-prototype-scriptaculous-persistent-grid-sorting-goodness/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1eaa45fee6a2b0c4b479b2982a4274f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mattstine</media:title>
		</media:content>
	</item>
		<item>
		<title>LOTY Time Again: Scala or Clojure?!?!</title>
		<link>http://mattstine.com/2009/04/02/loty-time-again-scala-or-clojure/</link>
		<comments>http://mattstine.com/2009/04/02/loty-time-again-scala-or-clojure/#comments</comments>
		<pubDate>Thu, 02 Apr 2009 20:21:21 +0000</pubDate>
		<dc:creator>mattstine</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[dynamiclanguages]]></category>
		<category><![CDATA[goals]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[programming]]></category>

		<guid isPermaLink="false">http://www.mattstine.com/?p=113</guid>
		<description><![CDATA[In 2007 I established several professional development goals (and later reported my progress on these), one of which was to learn Groovy and Grails. This goal stemmed from the continually referenced idea from The Pragmatic Programmer to &#8220;learn a new language every year.&#8221; This idea has become so ubiquitous that it even has it&#8217;s own [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=113&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In 2007 <a href="http://www.mattstine.com/2007/07/10/my-professional-development-goals-for-2007-2008/">I established several professional development goals</a> (<a href="http://www.mattstine.com/2008/01/02/mid-year-review-my-professional-development-goals-for-2007-2008/">and later reported my progress on these</a>), one of which was to learn Groovy and Grails. This goal stemmed from the continually referenced idea from <em>The Pragmatic Programmer</em> to &#8220;learn a new language every year.&#8221; This idea has become so ubiquitous that it even has it&#8217;s own four-letter acronym, LOTY (Language of the Year).</p>
<p>Since establishing and reporting on these goals, I&#8217;ve had several things get in the way of fully realizing all of them. However, I can safely say that in the last two years I have mastered enough Groovy and Grails that they no longer fit in the LOTY category. At this point they&#8217;re really not showing my anything that is causing any paradigm shifts for me. They&#8217;re comfortable. When I learn a new feature, it just seems to make sense, and nothing surprises me anymore. Languages like these aren&#8217;t good LOTY candidates because one of the purposes of learning a LOTY is to challenge and change your ideas about programming. Groovy doesn&#8217;t do this for me anymore. It&#8217;s time to move on (not to say that I&#8217;m dropping Groovy and Grails as a tool &#8211; I&#8217;m using them more now than ever &#8211; they&#8217;re just not a learning tool for me anymore).</p>
<p>So, at this point I want to delve into a language that attempts to tackle the concurrent/multicore programming challenge. I&#8217;d like to stay on the JVM because I appreciate the benefits that it brings as a platform, so for now Erlang is out. The two leading candidates in the JVM/concurrent/multicore arena seem to be <a href="http://www.scala-lang.org/">Scala</a> and <a href="http://clojure.org/">Clojure</a>. An added benefit of both of these languages is that they support the functional paradigm, something I haven&#8217;t really played with since my computer science education days and a very interesting language named Haskell.</p>
<p>Scala is a multiparadigm language, supporting both object-oriented and functional constructs. It is statically typed, yet offers very nice type inference. Clojure, on the other hand, is a functional Lisp derivative with almost no OO constructs that is dynamically typed. Both are designed to enable concurrent programming. Which one do I choose? I open the floor for comments.</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattstine.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattstine.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mattstine.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mattstine.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mattstine.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mattstine.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mattstine.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mattstine.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mattstine.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mattstine.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mattstine.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mattstine.wordpress.com/113/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mattstine.wordpress.com/113/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mattstine.wordpress.com/113/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=113&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattstine.com/2009/04/02/loty-time-again-scala-or-clojure/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1eaa45fee6a2b0c4b479b2982a4274f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mattstine</media:title>
		</media:content>
	</item>
		<item>
		<title>Deploying Grails with Groovy</title>
		<link>http://mattstine.com/2009/03/29/deploying-grails-with-groovy/</link>
		<comments>http://mattstine.com/2009/03/29/deploying-grails-with-groovy/#comments</comments>
		<pubDate>Sun, 29 Mar 2009 08:38:09 +0000</pubDate>
		<dc:creator>mattstine</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[deployment]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>

		<guid isPermaLink="false">http://www.mattstine.com/?p=89</guid>
		<description><![CDATA[Interesting title, eh? Maybe this one will make it through Glen&#8217;s filter at GroovyBlogs.org. On to the meat. I&#8217;ve been steadily working on a couple of Grails applications, one being the website for the Memphis JUG, and another being the e-commerce site for my wife&#8217;s soon to be launched designer stationery business. Just like your [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=89&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Interesting title, eh? Maybe this one will make it through Glen&#8217;s filter at <a href="http://groovyblogs.org">GroovyBlogs.org</a>.</p>
<p>On to the meat. I&#8217;ve been steadily working on a couple of Grails applications, one being the website for the <a href="http://www.memphisjug.org">Memphis JUG</a>, and another being the e-commerce site for my wife&#8217;s soon to be launched designer stationery business. Just like your average Grails developer, I&#8217;ve been happily coding away at 127.0.0.1 using the good old development Jetty+MySQL stack. Well, in the last week or so it&#8217;s come time to actually deploy both of these applications into production. I started out last weekend with the Memphis JUG site. My first approach was to build the WAR file locally and then &#8220;scp&#8221; it up to the server.</p>
<p>YMMV, but the upload speed on my DSL connection is horrible! After doing this three or four times in one night, waiting 15-20 minutes for the WAR to upload each time (Grails WAR&#8217;s are rather thick when carrying all of the dependencies along), I decided to myself, &#8220;There must be a better way to do this.&#8221;</p>
<p>Fast forward a week and here I sit working on the first &#8220;pre-production&#8221; release of my wife&#8217;s store site. With quite a bit of time on my hands during these &#8220;dark and early&#8221; hours (a story for a later entry), I decided it was time for the experiment.</p>
<p>Each of these projects is hosted at GitHub, so the process that I mapped out in my mind looked like this:</p>
<ol>
<li>Check out the latest code from GitHub</li>
<li>Run &#8220;grails war&#8221;</li>
<li>Stop the Tomcat service (my hosting provider sets up Tomcat to run as a service)</li>
<li>Delete the remnants of the previous deployment from Tomcat&#8217;s deployment directory</li>
<li>Copy the new WAR file to Tomcat&#8217;s deployment directory</li>
<li>Start the Tomcat service</li>
</ol>
<p>By the way, I forgot to mention that before doing all of this I moved the production data source definition from being locally defined to being a JNDI lookup within Tomcat. This posed its own challenge, which I&#8217;ll blog about a bit later.</p>
<p>Anyway, back to the deployment. I though this would be an excellent opportunity to take <a href="http://groovy.codehaus.org/Using+Ant+from+Groovy">Groovy&#8217;s Antbuilder</a> out for a spin. Here&#8217;s an example of what I put together:</p>
<pre class="brush: groovy">
#!/usr/bin/env groovy

def ant = new AntBuilder()

//Update the codebase from GitHub
ant.exec(executable:'git', dir: "${PROJECT_DIR}") {
        arg(value:'pull')
}

//Generate the WAR file using Ant
ant.ant(dir:'"${PROJECT_DIR}"', target: 'war')

//Stop Tomcat
ant.exec(executable:'service') {
        arg(line:'tomcat6 stop')
}

//Delete the old webapp contents from Tomcat's deploy directory
ant.delete(includeemptydirs:'true', verbose:'true') {
        fileset(dir:"${CONTEXT_ROOT_DIR}", includes:'**/*')
}

//Copy the new WAR file to Tomcat's deploy directory
ant.copy(file:"${WAR_FILE}", tofile:"${CONTEXT_ROOT_DIR}/ROOT.war")

//Start Tomcat
ant.exec(executable:'service') {
        arg(line:'tomcat6 start')
}
</pre>
<p>As you can see, I have a few undefined Groovy constants in there. Let&#8217;s just say I didn&#8217;t want to expose ALL of the details of my server.</p>
<p>At any rate, it&#8217;s pretty simple. One word of warning &#8211; if you&#8217;re using Ehcache, make sure to add it to your ivy.xml dependencies, or the Ant build won&#8217;t bring it in like running &#8220;grails war&#8221; will. I hope someone finds this simple script useful. Enjoy!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattstine.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattstine.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mattstine.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mattstine.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mattstine.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mattstine.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mattstine.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mattstine.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mattstine.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mattstine.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mattstine.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mattstine.wordpress.com/89/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mattstine.wordpress.com/89/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mattstine.wordpress.com/89/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=89&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattstine.com/2009/03/29/deploying-grails-with-groovy/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1eaa45fee6a2b0c4b479b2982a4274f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mattstine</media:title>
		</media:content>
	</item>
		<item>
		<title>Need a Textile engine? Look no further than Plextile!</title>
		<link>http://mattstine.com/2009/03/26/need-a-textile-engine-look-no-further-than-plextile/</link>
		<comments>http://mattstine.com/2009/03/26/need-a-textile-engine-look-no-further-than-plextile/#comments</comments>
		<pubDate>Thu, 26 Mar 2009 21:23:46 +0000</pubDate>
		<dc:creator>mattstine</dc:creator>
				<category><![CDATA[CodeProject]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[textile]]></category>

		<guid isPermaLink="false">http://www.mattstine.com/?p=81</guid>
		<description><![CDATA[In finishing up the first release of JUG Nexus, the open source engine (http://github.com/mstine/jug-nexus/tree/master) behind the new Memphis JUG website, I needed to put a good Textile engine in place. I really don&#8217;t care for writing actual HTML in a content management system, and JUG Nexus being a lightweight CMS, I wanted a lightweight markup [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=81&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>In finishing up the first release of JUG Nexus, the open source engine (<a href="http://github.com/mstine/jug-nexus/tree/master">http://github.com/mstine/jug-nexus/tree/master</a>) behind the new Memphis JUG website, I needed to put a good <a href="http://www.textism.com/tools/textile/">Textile</a> engine in place. I really don&#8217;t care for writing actual HTML in a content management system, and JUG Nexus being a lightweight CMS, I wanted a lightweight markup syntax for entering the details of upcoming JUG meetings. Textile is exactly that, and is also used for entering content into the very useful <a href="http://jugevents.org">JUGEvents</a> system produced by <a href="http://www.jugpadova.it/">JUG Padova</a> for the Java User Group community at large. I tried out several different engines, and none of them seemed to be very robust when it came to edge cases in the markup. For example, if I want to produce a hyperlink to a website, the textile format is the following:</p>
<p><code><br />
"Linked Text":http://www.site.com<br />
</code></p>
<p>This syntax will result in the following HTML:</p>
<pre class="brush: xml">
&lt;a href="http://www.site.com"&gt;Linked Text&lt;/a&gt;
</pre>
<p>Unfortunately, if you have a bang (!) in your &#8220;Linked Text,&#8221; most of the Textile engines that I used would not recognize it as an HTML link. Plextile does!</p>
<p>The only drawback, however minimal, to using Plextile is that it does not come with a pre-packaged JAR file. You have to take the compiled code and JAR it yourself. Now, for free, I&#8217;ll include how I integrated Plextile with Grails. Grails has a very nice codec feature that provides a facility to register encoders and decoders of textual data as methods on any object. Grails searches for classes following the convention <code>XCodec</code> and dynamically registers <code>encodeAsX</code> and <code>decodeX</code> methods on <code>java.lang.Object</code> so that any data can be encoded and decoded. Enter the <code>TextileCodec</code>:</p>
<pre class="brush: groovy">
import com.plink.plextile.TextParser

class TextileCodec {

   static encode = {str -&gt;
      new TextParser().parseTextile(str, true)
   }

}
</pre>
<p>Believe it or not, that&#8217;s it! Here&#8217;s the GSP template for rendering a JUG meeting:</p>
<pre class="brush: xml">
&lt;div class="post"&gt;
  &lt;h2&gt;${event.title}&lt;br/&gt;&lt;br/&gt;&lt;g:formatDate format="EEEE, MMMM dd, yyyy" date="${event.startTime}"/&gt;&lt;br/&gt;&lt;g:formatDate format="h:mm" date="${event.startTime}"/&gt;-&lt;g:formatDate format="h:mm a" date="${event.endTime}"/&gt;&lt;br/&gt;&lt;g:if test="${!event.archived}"&gt;&lt;a href="http://jugevents.org/jugevents/event/${event.jugEventsId}"&gt;Click HERE to register!&lt;/a&gt;&lt;/g:if&gt;&lt;/h2&gt;
  &lt;div class="entry"&gt;
    &lt;h2 class="title"&gt;Speaker/Topic:&lt;/h2&gt;
    &lt;p&gt;${event.description.encodeAsTextile()}&lt;/p&gt;
    &lt;h2 class="title"&gt;Location/Directions:&lt;/h2&gt;
    &lt;p&gt;${event.location}&lt;/p&gt;
    &lt;p&gt;${event.directions.encodeAsTextile()}&lt;/p&gt;
  &lt;/div&gt;
&lt;/div&gt;
</pre>
<p>Enjoy!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattstine.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattstine.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mattstine.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mattstine.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mattstine.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mattstine.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mattstine.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mattstine.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mattstine.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mattstine.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mattstine.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mattstine.wordpress.com/81/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mattstine.wordpress.com/81/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mattstine.wordpress.com/81/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=81&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattstine.com/2009/03/26/need-a-textile-engine-look-no-further-than-plextile/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1eaa45fee6a2b0c4b479b2982a4274f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mattstine</media:title>
		</media:content>
	</item>
		<item>
		<title>Grails 1.0 Released!</title>
		<link>http://mattstine.com/2008/02/05/grails-10-released/</link>
		<comments>http://mattstine.com/2008/02/05/grails-10-released/#comments</comments>
		<pubDate>Tue, 05 Feb 2008 15:48:00 +0000</pubDate>
		<dc:creator>mattstine</dc:creator>
				<category><![CDATA[grails]]></category>
		<category><![CDATA[groovy]]></category>
		<category><![CDATA[java]]></category>

		<guid isPermaLink="false">http://www.mattstine.com/?p=59</guid>
		<description><![CDATA[Grails, by far my favorite of the JVM dynamic language frameworks, was released this morning, with a snazzy, new, &#8220;Web 2.0 style&#8221; website to boot. Congratulations Graeme and company on all of your hard work!<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=59&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p><a href="http://grails.org/Home">Grails</a>, by far my favorite of the JVM dynamic language frameworks, was released this morning, with a snazzy, new, &#8220;Web 2.0 style&#8221; website to boot. Congratulations Graeme and company on all of your hard work!</p>
<br /><img alt="" border="0" src="http://feeds.wordpress.com/1.0/categories/mattstine.wordpress.com/59/" /> <img alt="" border="0" src="http://feeds.wordpress.com/1.0/tags/mattstine.wordpress.com/59/" /> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/mattstine.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/mattstine.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/mattstine.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/mattstine.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/mattstine.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/mattstine.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/mattstine.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/mattstine.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/mattstine.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/mattstine.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/mattstine.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/mattstine.wordpress.com/59/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/mattstine.wordpress.com/59/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/mattstine.wordpress.com/59/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=mattstine.com&amp;blog=58954&amp;post=59&amp;subd=mattstine&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://mattstine.com/2008/02/05/grails-10-released/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://1.gravatar.com/avatar/1eaa45fee6a2b0c4b479b2982a4274f4?s=96&#38;d=identicon&#38;r=G" medium="image">
			<media:title type="html">mattstine</media:title>
		</media:content>
	</item>
	</channel>
</rss>
