<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-1649150308934898417</id><updated>2011-11-13T22:29:26.914Z</updated><category term='Bash Fu'/><category term='JPA'/><category term='Dev Tools'/><category term='XSLT'/><category term='WebFlow'/><category term='General'/><category term='Craftsmanship'/><category term='Maven'/><category term='Rails'/><category term='Tapestry 5'/><category term='RoR'/><category term='Mac'/><category term='Rant'/><category term='Spring'/><category term='JavaScript'/><category term='Java'/><category term='Start ups'/><category term='Fear'/><category term='Groovy'/><category term='Google'/><category term='Random Tech'/><category term='Open Source'/><category term='Testing'/><title type='text'>Electric Politician</title><subtitle type='html'>Some pithy slogan goes here.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>53</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-5724540135618148440</id><published>2011-02-11T20:17:00.000Z</published><updated>2011-02-11T20:17:22.908Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Rant'/><title type='text'>Banks and cards from different country with the same PayPal email</title><content type='html'>...well sort of.&lt;br /&gt;
&lt;br /&gt;
PayPal doesn't have the concept of people that live or travel to different countries. If you try and setup banks or credit cards in two different countries you will find it impossible. For starters, the address fields are limited to your initial country and there is no way around it.&lt;br /&gt;
&lt;br /&gt;
Call PayPal and they say that you cannot have bank accounts or credit cards from different countries on the same account - why - you just can't so don't ask. They suggest creating a new email with an extra number on the end for each country. WHAT! I'm not sure about you, but I already have far too many username/passwords to remember as it is.&lt;br /&gt;
&lt;br /&gt;
For a long time I just accepted this situations and only had a single account and just paid for everything with normal channels in other countries. However, that recently changed when I wanted to buy something from UK ebay and the only channel was PayPal. I tried once more to add my UK credit card to my Canadian PayPal account. The billing address was a mess and clearly wasn't going to clear if I tried it.&lt;br /&gt;
&lt;br /&gt;
It was at this point I started looking into creating a new email address for the UK to sign up for a second PayPal account. And that's when it hit me. I use gmail as my main email and gmail allows you to put periods anywhere in your name without it making a difference. That is. johndoe and john.doe are the same in googles eyes. In fact j.o.h.n.d.o.e is the same as johndoe. But to PayPal they are very different. Bingo!&lt;br /&gt;
&lt;br /&gt;
I simply put a full stop between my first and last names of my email and I have a second PayPal account with the same email address in a different country.&lt;br /&gt;
&lt;br /&gt;
All my PayPal notifications from both accounts go to the same gmail address. &amp;nbsp;I don't have to find a new email address, remember a new password (yes I use the same password for both&amp;nbsp;PayPal&amp;nbsp;accounts - but it is insanely long and complex.) I can buy using PayPal in each country.&amp;nbsp;I suppose I could also transfer between each account, although I've not actually tried that and it probably isn't a service I really need.&lt;br /&gt;
&lt;br /&gt;
I really don't like PayPal, I think their model is very broken and I doubt it will ever chip away at Visa or Master Card until it changes. &amp;nbsp;Now I have a UK PayPal account I still couldn't use my UK credit card because I had to wait 2-3 days to verify my account. Surely Visa and Master Card have done that already, they have 3D secure for online transactions, why does PayPal always seem to block your use of their service?&lt;br /&gt;
&lt;br /&gt;
I hope this workaround can help you in time of need - just don't expect it to work without delay.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-5724540135618148440?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/5724540135618148440/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2011/02/banks-and-cards-from-different-country.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/5724540135618148440'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/5724540135618148440'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2011/02/banks-and-cards-from-different-country.html' title='Banks and cards from different country with the same PayPal email'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-3261939438871646510</id><published>2011-01-28T14:53:00.000Z</published><updated>2011-01-28T14:53:56.035Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Bash Fu'/><category scheme='http://www.blogger.com/atom/ns#' term='Rails'/><title type='text'>Get started with Rails with all the Railscast movies offline</title><content type='html'>Getting offline content from &lt;a href="http://railscasts.com/"&gt;Railscasts.com&lt;/a&gt;&amp;nbsp;is very handy.&lt;br /&gt;
&lt;br /&gt;
This script is a slight adjustment from&amp;nbsp;&lt;a href="http://niczsoft.com/2010/01/download-all-railscasts/"&gt;http://niczsoft.com/2010/01/download-all-railscasts/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
This version gets the railscast movies starting with first, or oldest, movie rather than starting at the lastest first.&lt;br /&gt;
&lt;br /&gt;
&lt;pre class="brush: bash"&gt;wget -q -O - http://feeds.feedburner.com/railscasts |\
awk -F \" '/media:content/ {print $4}' | \
perl -e 'print reverse &amp;lt;&amp;gt;' | \
wget -i - -c

&lt;/pre&gt;&lt;br /&gt;
I urge you to &lt;a href="http://railscasts.com/give_back"&gt;read this&lt;/a&gt; from Railscasts.com and give back in someway.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-3261939438871646510?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/3261939438871646510/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2011/01/get-started-with-rails-with-all.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/3261939438871646510'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/3261939438871646510'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2011/01/get-started-with-rails-with-all.html' title='Get started with Rails with all the Railscast movies offline'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-2890121141557126984</id><published>2011-01-25T23:31:00.000Z</published><updated>2011-01-25T23:31:27.943Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Craftsmanship'/><title type='text'>The lazy pattern</title><content type='html'>"A little bit won't hurt. A little bit doesn't matter." I hear this more than I want and so I'm having to write this little rant to cool me off.&lt;br /&gt;
&lt;br /&gt;
Writing code that works is relatively easy. Writing code that is too complicated is easy too. The balance between easy and over complicated is hard to find. Writing good,&amp;nbsp;&lt;a href="http://en.wikipedia.org/wiki/Solid_(object-oriented_design)"&gt;SOLID&lt;/a&gt;, object-oriented code is the goal.&lt;br /&gt;
&lt;br /&gt;
Every shortcut you do shows to others in your team that it is okay to use shortcuts as well.&amp;nbsp;When a developer is asked to extend a class or add a feature they often just copy what they see around them. And if that is a bunch of little shortcuts it can rapidly become a big problem.&amp;nbsp;&lt;br /&gt;
&lt;br /&gt;
I rarely see Developers want to improve the camp ground. (Uncle Bob asks us to follow the &lt;a href="http://programmer.97things.oreilly.com/wiki/index.php/The_Boy_Scout_Rule"&gt;boy scout rule&lt;/a&gt; and leave the camp ground just a little cleaner than it was before.) It's hard work, but I love this rule. I follow it happily.&lt;br /&gt;
&lt;br /&gt;
Take the sink in a student house; if someone leaves a dirty bowl in the sink, the next person comes a long and thinks it's okay to stack their dirty bowl next to the one already there. Before long there are lots and lots of dirty dishes in the sink and it's a big job to clean it all up.&lt;br /&gt;
&lt;br /&gt;
Taking the dirty dishes analogy a little further.&lt;br /&gt;
&lt;br /&gt;
If you are the sort of person that wants to wash their dirty dishes but finds that the sink has dirty items blocking your way, all of a sudden it's a bigger job than you first thought - do you clean all the dishes or do you copy what the other guy did?&lt;br /&gt;
&lt;br /&gt;
This decision point is where that devil laziness really comes into play. Do you do a little bit of lazy code, next to the other little bit of lazy code, after all it isn't really that big a deal.&lt;br /&gt;
&lt;br /&gt;
And so it goes on, a little bit here, a little bit there, and before long everyone is copying the lazy pattern.&lt;br /&gt;
&lt;br /&gt;
I find String to be one of those little lazy decisions that is easy to make, easy to follow and very easy to stack up and get out of control.&lt;br /&gt;
&lt;br /&gt;
For example, the use of String for what really should be a &lt;a href="http://en.wikipedia.org/wiki/Domain-driven_design#Building_Blocks_of_DDD"&gt;value object&lt;/a&gt;, an object that has no conceptual identity. I would extend this to many Strings &amp;nbsp;like a person's name, a telephone number or a postal code - even if these objects do nothing more than wrap String.&lt;br /&gt;
&lt;br /&gt;
Some would, I'm sure, argue this is over engineering. But if I've got a constructor that takes three parameters, all of them Strings, creating value objects gives you at least some type safety, and an object that can be extended with more behaviour down the line. &amp;nbsp;Some would say that's just good OO, without it, it's just a bunch of Strings.&lt;br /&gt;
&lt;br /&gt;
I'm not innocent here - I've cut the corners in the past. &amp;nbsp;But what I have learnt over the last couple of years is to always put that extra effort in, create something that is built around good objects and follow the boy scout rule. It really does pay off and the alternative always bites you in the end.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-2890121141557126984?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/2890121141557126984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2011/01/lazy-pattern.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/2890121141557126984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/2890121141557126984'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2011/01/lazy-pattern.html' title='The lazy pattern'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-899643178751274448</id><published>2011-01-11T07:57:00.000Z</published><updated>2011-01-11T07:57:06.619Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Rant'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><title type='text'>Google URL Shortening get API</title><content type='html'>The long arm of google has found its way into the url shortening space.&amp;nbsp;&lt;a href="http://googlecode.blogspot.com/2011/01/google-url-shortener-gets-api.html"&gt;http://googlecode.blogspot.com/2011/01/google-url-shortener-gets-api.html&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
It seems there is no area that google won't go to track, trace and analyse your data. &amp;nbsp;Don't get me wrong, I love many google apps, all of which I use free of charge. That is, I don't actually pay them direct. What they do with my time in the application makes them money; and good luck to them.&lt;br /&gt;
&lt;br /&gt;
I did find it particularly funny to see goo.gl url shortening is the fastest available.&amp;nbsp;&lt;a href="http://royal.pingdom.com/2010/10/29/is-goo-gl-really-the-fastest-url-shortener-chart/"&gt;http://royal.pingdom.com/2010/10/29/is-goo-gl-really-the-fastest-url-shortener-chart/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
I mean...how fast does url shortening have to be!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-899643178751274448?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/899643178751274448/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2011/01/google-url-shortening-get-api.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/899643178751274448'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/899643178751274448'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2011/01/google-url-shortening-get-api.html' title='Google URL Shortening get API'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-3691785719871012182</id><published>2011-01-10T14:00:00.001Z</published><updated>2011-01-11T22:14:35.472Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Start ups'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Find the fun, forget the money</title><content type='html'>One of my goals this year is to actually put some of those ideas I have rattling around my brain into code, and even better into other peoples hands to use.&lt;br /&gt;
&lt;br /&gt;
I did put one caveat to this goal: &lt;b&gt;It would be for fun, not money.&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
I love start ups - if that is what I should call it - the energy is in tune with my frequency. I'm going to be working on a couple of projects, with a couple of like minded friends, and I am already enjoying the collaboration over technology.&lt;br /&gt;
&lt;br /&gt;
The will be no hocket stick projection of revenue, no early retirement plans in the south of France, no VC pitch.&amp;nbsp;Going through the whole process is what I feel is important. Taking an idea; then create that idea; and finally letting it out early into the wild for peer review.&lt;br /&gt;
&lt;br /&gt;
Making money from the web is notoriously hard.  I recently read this blog post which I tend to agree with: &lt;a href="http://paraschopra.com/blog/entrepreneurship/webapp-is-not-going-to-make-money.htm"&gt;Sorry, your “cool” webapp is probably not going to make money&lt;/a&gt;&amp;nbsp;That said, this shouldn't put you off, as the post suggests there is money to be made, but don't focus on money.&lt;br /&gt;
&lt;br /&gt;
Focusing on money never actually helps innovation or motivation. &lt;a href="http://www.youtube.com/watch?v=u6XAPnuFjJc"&gt;RSA Animate - Drive: The surprising truth about what motivates us&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
So practice, practice, practice is mantra for 2011. Delivery something useful, again and again. Each time there will be failures and falls that will have to be overcome, and each of those lessons will hold true value. &lt;br /&gt;
&lt;br /&gt;
And you never know, perhaps one of these days we might create something that people love to use - and that's got to be worth more than money, right?&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-3691785719871012182?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/3691785719871012182/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2011/01/find-fun-forget-money.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/3691785719871012182'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/3691785719871012182'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2011/01/find-fun-forget-money.html' title='Find the fun, forget the money'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-2385868617619815439</id><published>2010-02-03T21:30:00.047Z</published><updated>2010-02-03T22:13:26.805Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Checked vs Unchecked: That old chestnut!</title><content type='html'>I really thought this one had gone to bed, but recently a debate on checked vs unchecked exceptions arrived at my door.&lt;br /&gt;
&lt;br /&gt;
I'm associated with this &lt;a href="http://github.com/opsb/butler-io"&gt;Butler IO&lt;/a&gt;, it's basically a helper for getting and writing resources.&lt;br /&gt;
&lt;br /&gt;
Does things like this:&lt;br /&gt;
&lt;pre class="brush: java"&gt;String fromClasspath  = ButlerIO.textFrom( "res:articles/steve_jobs.txt" );
&lt;/pre&gt;&lt;br /&gt;
The workings of textFrom basically come from this method.&lt;br /&gt;
&lt;pre class="brush: java"&gt;public static byte [] bytesFrom(InputStream inputStream) {
    ByteArrayOutputStream out = new ByteArrayOutputStream(BUFFER_SIZE);
    try {
        copy(inputStream, out);
 return out.toByteArray();
    } catch (IOException e) {
        throw new RuntimeException(e);
    }
}
&lt;/pre&gt;&lt;br /&gt;
The project wasn't up a day and a complaint was received about catching the checked and re-throw a runtime exception. In their words; "... throwing an unchecked exception here is just pampering the user in false safety. Checked exceptions are there for a good reason"&lt;br /&gt;
&lt;br /&gt;
This project was built to help make clean code and has followed &lt;a href="http://www.mindview.net/Etc/Discussions/CheckedExceptions"&gt;Bruce Eckel's&lt;/a&gt; thoughts on this subject of exceptions.&lt;br /&gt;
&lt;br /&gt;
I can't think of a time when you can recover from an IOException, and this way can identify programmer errors early and clearly at runtime. The utility doesn't enforce you to catch any exception, which makes for cleaner code...right?&lt;br /&gt;
&lt;br /&gt;
Isn't the point that any error handling be the choice of the caller; Butler can't do anything about a missing file, and doesn't presume to know what the caller wants to do either.&lt;br /&gt;
&lt;br /&gt;
Have I got this wrong? I don't think so! But I would appreciate some feedback from you guys. Thanks.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-2385868617619815439?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/2385868617619815439/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2010/02/checked-vs-unchecked-that-old-chestnut.html#comment-form' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/2385868617619815439'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/2385868617619815439'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2010/02/checked-vs-unchecked-that-old-chestnut.html' title='Checked vs Unchecked: That old chestnut!'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-6529360828237235639</id><published>2010-02-02T12:53:00.000Z</published><updated>2010-02-02T12:53:03.949Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Do you have conference envy?</title><content type='html'>Conferences are big business. It's the hotels, it's the conference centres and its the major players sponsoring the event. In the technology sector — and software — you can go to QCon, ApacheCon, JAOO, and those are just the big ones. &lt;br /&gt;
&lt;br /&gt;
These yearly conferences are filled with some of the best — and dare I say iconic — players in the business. The people that the write books you study, the blogs you read, the practices you follow. These gatherings give you the ability to see, hear and possibly interact with these incredible minds....but only if you are rich!&lt;br /&gt;
&lt;br /&gt;
At £2000 a piece — and that's just to go and not including hotel and travel — it's not an amount easy to swallow or cough up. Perhaps if the company you work for has money or is willing to part with money on your behalf, you might be able to attend one of these grand events. If you work for a start up or are self-employed or a company that doesn't value its employees attending gala events, you're bang out of luck.&lt;br /&gt;
&lt;br /&gt;
You'll just have to wait and hope for the video to pop on InfoQ. &lt;br /&gt;
&lt;br /&gt;
The video of the presentation will often suffice, all stuff no fluff. But what I object to is this notion that these conferences are a "must do". Is this conference envy? Potential employers ask about potential employeses in interview and damn it I even ask people interviews if they have attended them. Some even dare to bill themselves as "By Developers for developers." What a pill of poop!&lt;br /&gt;
&lt;br /&gt;
Conferences aren't always a lost cause. There are good value events which enable passionate developers to mingle the the like minded and hear from their idols. XP Days has always been reasonably priced and there was even a free Scale Camp in London late last year that boasted some impressive speakers. &lt;br /&gt;
&lt;br /&gt;
But just remember: 2000  quid can buy you a lot of books.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-6529360828237235639?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/6529360828237235639/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2010/02/do-you-have-conference-envy.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/6529360828237235639'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/6529360828237235639'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2010/02/do-you-have-conference-envy.html' title='Do you have conference envy?'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-3321575513346276783</id><published>2010-01-29T15:16:00.002Z</published><updated>2010-01-29T15:35:03.738Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Top 10 reasons not to do a top 10</title><content type='html'>&lt;ol&gt;
   &lt;li value="10"&gt;Seeing them pop up in your rss feed can make you bitter.&lt;/li&gt;
   &lt;li value="9"&gt;They wouldn't even look good on an over-sized comedy iTouch.&lt;/li&gt;
   &lt;li value="8"&gt;You might be tempted to waste time commenting, "Gee, thanks, this was awesome!"&lt;/li&gt;
   &lt;li value="7"&gt;They will suck your will to live right out of you.&lt;/li&gt;
   &lt;li value="6"&gt;Your list is already out of date.&lt;/li&gt;
   &lt;li value="5"&gt;They always contain useless arbitrary statistics.&lt;/li&gt;
   &lt;li value="4"&gt;It's a cheap way to get traffic to your tumbleweed blog (guilty as charged.)&lt;/li&gt;
   &lt;li value="3"&gt;They made me waste time thinking about this damn list.&lt;/li&gt;
   &lt;li value="2"&gt;You are still reading this, although this list sucks the most.&lt;/li&gt;
&lt;/ol&gt;
...
...
...
...
&lt;ol&gt;
 &lt;li value="1"&gt;Well....you can think of the number one reason why you shouldn't make a top 10.&lt;/li&gt;
&lt;/ol&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-3321575513346276783?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/3321575513346276783/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2010/01/top-10-reasons-not-to-do-top-10.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/3321575513346276783'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/3321575513346276783'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2010/01/top-10-reasons-not-to-do-top-10.html' title='Top 10 reasons not to do a top 10'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-2499948385261321047</id><published>2010-01-29T12:04:00.021Z</published><updated>2010-03-05T14:58:22.346Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='XSLT'/><title type='text'>Add Custom Font Using FOP</title><content type='html'>This post is about Java PDF generation using Apache FOP and XSL-FO.     Your client wants a font in their PDF report generation that isn't available in the system.   I found the &lt;a href="http://xmlgraphics.apache.org/fop/trunk/fonts.htm"&gt;documentation&lt;/a&gt; a little over the top and obscured what I needed to do. Therefore in 3 easy steps this is what you need to do:   &lt;ol&gt;&lt;li&gt;Create a metrics xml  of the font using FOP Utility.&lt;/li&gt;
&lt;li&gt;Define custom font in FOP configuration. &lt;/li&gt;
&lt;li&gt;Use font in XSLT.&lt;/li&gt;
&lt;/ol&gt;&lt;span style="font-weight: bold;"&gt;Create a metrics xml  of the font using FOP Utility&lt;/span&gt;   I'm using maven and therefore it is easier to create a simple class within my project to call FOPs font util rather than messing about with &lt;a href="http://xmlgraphics.apache.org/fop/trunk/fonts.html#advanced"&gt;command line java&lt;/a&gt; and classpaths. &lt;pre class="brush: java"&gt;import org.apache.fop.fonts.apps.TTFReader;

public class ConvertFont {
public static void main(String[] args) {
    TTFReader.main(new String[] {"/home/farrd/fonts/TheSans","/home/farrd/fonts/TheSans.xml"});
}
}
&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;Define custom font in FOP configuration&lt;/span&gt;  Copy the font and the metric xml file into your project so that it is available on the classpath. Now create a &lt;a href="http://xmlgraphics.apache.org/fop/trunk/configuration.html"&gt;fop configuration file&lt;/a&gt; and define the font. Apache FOP uses &lt;a href="http://commons.apache.org/vfs/"&gt;Apache FVS&lt;/a&gt; so you can prefix the location of the font files with res and it will resolve them correctly. (nice!) &lt;pre class="brush: xml"&gt;&lt;fop version="1.0"&gt;
&lt;renderers&gt;
&lt;renderer mime="application/pdf"&gt;
&lt;fonts&gt;
&lt;span url="res:font/TheSans.xml" mode="single-byte" kerning="yes"&gt;
  &lt;font-triplet name="TheSans" style="" weight="normal"&gt;
&lt;/font-triplet&gt;&lt;/span&gt;
&lt;/fonts&gt;
&lt;/renderer&gt;
&lt;/renderers&gt;
&lt;/fop&gt;
&lt;/pre&gt;&lt;span style="font-weight: bold;"&gt;Use font in XSLT&lt;/span&gt;  When constructing your FopFactory, set the above configuration. I'm using &lt;a href="http://github.com/opsb/butler-io"&gt;BulterIO&lt;/a&gt; to resolve the file. (this is a nice also [yes, shameless self plug as I've worked on some of the code in &lt;a href="http://github.com/opsb/butler-io"&gt;BulterIO&lt;/a&gt;]) &lt;pre class="brush: java"&gt;...
FopFactory fopFactory = FopFactory.newInstance();
try {
    fopFactory.setUserConfig(ButlerIO.fileAt("fop_config.xml"));
} catch (Exception e) {
    throw new RuntimeException(e);
}

fopFactory.setURIResolver(new URIResolver() {
    public Source resolve(String href, String base) throws TransformerException {
        return new StreamSource(ButlerIO.inputStreamFrom(href));
    }
});
...

&lt;/pre&gt;You can now reference your font in the normal way within your XSLT. &lt;pre class="brush: xml"&gt;...
&lt;fo:page-sequence reference="cover"&gt;
&lt;fo:flow name="xsl-region-body" family="TheSans"&gt;
...
&lt;/fo:flow&gt;
&lt;/fo:page-sequence&gt;
...
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-2499948385261321047?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/2499948385261321047/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2010/01/add-custom-font-using-fop.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/2499948385261321047'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/2499948385261321047'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2010/01/add-custom-font-using-fop.html' title='Add Custom Font Using FOP'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-3705874175341062541</id><published>2010-01-14T15:17:00.002Z</published><updated>2010-01-14T16:23:32.462Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Groovy'/><title type='text'>MapReduce In Groovy</title><content type='html'>I came across an old post on Joel on Software about MapReduce and functions as first class citizens. You can read it &lt;a href="http://www.joelonsoftware.com/items/2006/08/01.html"&gt;here.&lt;/a&gt;

I thought I'd have a go at doing the examples in Groovy. I know these examples have been abstraction already in &lt;a href="http://groovy.codehaus.org/groovy-jdk/java/util/Collection.html#sum%28java.lang.Object%20initialValue,%20groovy.lang.Closure%20closure%29"&gt;1.5+&lt;/a&gt;, but that takes the fun out of this exercise.
&lt;br/&gt;
&lt;br/&gt;
Closures to sum and join
&lt;pre class="brush: groovy"&gt;
def d = [1,2,3,4]
def c = ["a","b","c"]

def sum = {param -&gt;
  def result = 0
  param.each{result += it}
  result
}

def join2 = {param -&gt;
  def result = ""
  param.each{result += it}
  result
}

println sum(d) // 10
println join2(c) // abc
&lt;/pre&gt;
&lt;br/&gt;&lt;br/&gt;
Abstract out the essence of sum and join into reduce
&lt;pre class="brush: groovy"&gt;
def d = [1,2,3,4]
def c = ["a","b","c"]

def reduce = { fn, a, init -&gt;
  def result = init
  a.each { result = fn(result,it) }  
  result
}

def addition = {param1, param2 -&gt; param1+param2}

println reduce (addition, d, 0)  // 10
println reduce (addition, c, "") // abc
&lt;/pre&gt;
&lt;br/&gt;&lt;br/&gt;
This isn't going to take on &lt;a href="http://labs.google.com/papers/mapreduce.html"&gt;Google&lt;/a&gt;, it was just a little exercise in functions as a first class citizens.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-3705874175341062541?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/3705874175341062541/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2010/01/mapreduce-in-groovy.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/3705874175341062541'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/3705874175341062541'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2010/01/mapreduce-in-groovy.html' title='MapReduce In Groovy'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-7563023545904920656</id><published>2009-09-23T13:03:00.000+01:00</published><updated>2009-09-23T13:11:02.142+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='RoR'/><title type='text'>Which is the best web framework?</title><content type='html'>This is always a lively debate after a few pints. It generally falls, with the Java heads I've had the pleasure of drinking with, to the best of the worst...cus they all suck in someway or another.

But for me, after watching this short webcast, the debate is over. 

&lt;a href="http://media.rubyonrails.org/video/rails_blog_2.mov"&gt;How to create an ajax enabled blog from scratch with atom feed in 15 minutes.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-7563023545904920656?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/7563023545904920656/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/09/which-is-best-web-framework_23.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/7563023545904920656'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/7563023545904920656'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/09/which-is-best-web-framework_23.html' title='Which is the best web framework?'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-7986579041621357235</id><published>2009-09-06T12:43:00.000+01:00</published><updated>2009-09-10T17:23:39.352+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Open Source'/><category scheme='http://www.blogger.com/atom/ns#' term='JPA'/><title type='text'>Manage JPA Tables Using An Active Collection</title><content type='html'>No ceremony, no fanfare: the first open source software that I'm part of.

&lt;a href="http://github.com/opsb/active-collections/tree/master#"&gt;http://github.com/opsb/active-collections/tree/master#&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-7986579041621357235?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/7986579041621357235/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/09/manage-jpa-tables-using-active.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/7986579041621357235'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/7986579041621357235'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/09/manage-jpa-tables-using-active.html' title='Manage JPA Tables Using An Active Collection'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-3775160360523767174</id><published>2009-09-01T15:07:00.000+01:00</published><updated>2009-09-01T15:34:20.070+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><category scheme='http://www.blogger.com/atom/ns#' term='Fear'/><title type='text'>Science of Motivation</title><content type='html'>I've worked for several companies where the idea of personal development time was put on the table. In all cases 'the business' disagreed with the idea with the usual fear of loss of productivity and therefore missed deadlines. 

This fear extends to agile software development, especially as software gets closer to a big release date; it's the developers that put in 80+ hour a weeks that are the ones that get the pat on the back from 'the business', rather than the developers that deliver high quality and robust software.

Now I sound a little bitter here, and perhaps I am, but I come from a science background and I like to question beliefs and do things because of evidence not for historical reasons.

A great many companies have a provincial attitude that is stranded in old fashion dogma, perhaps with videos like this time are a changin.

&lt;object height="340" width="560"&gt;&lt;param name="movie" value="http://www.youtube.com/v/rrkrvAUbU9Y&amp;amp;hl=en&amp;amp;fs=1&amp;amp;"&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;embed src="http://www.youtube.com/v/rrkrvAUbU9Y&amp;amp;hl=en&amp;amp;fs=1&amp;amp;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="340" width="560"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-3775160360523767174?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/3775160360523767174/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/09/science-of-motivation.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/3775160360523767174'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/3775160360523767174'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/09/science-of-motivation.html' title='Science of Motivation'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-779815135394903107</id><published>2009-08-14T12:37:00.000+01:00</published><updated>2009-08-14T12:46:53.057+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dev Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>How to find information about characters</title><content type='html'>Dealing with languages, characters, accents, squiggles, dots, dashes and all other type of wordy thingymebobs in software can be a real pain. ASCII, UTF, UNICODE, it's all a real mess (IMO.)

But rest assured, this site will come to your rescue: &lt;a href="http://www.fileformat.info/index.htm"&gt;fileformat.info&lt;/a&gt;

Everything and anything on characters for the digital world are covered here, with a very handy search capability.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-779815135394903107?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/779815135394903107/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/08/how-to-find-information-about.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/779815135394903107'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/779815135394903107'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/08/how-to-find-information-about.html' title='How to find information about characters'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-8042955656156543422</id><published>2009-08-07T09:27:00.000+01:00</published><updated>2009-08-07T10:01:13.430+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Tweet Tweet Tweet</title><content type='html'>I've finally joined &lt;a href="http://twitter.com/domfarr"&gt;Twitter&lt;/a&gt; and so far so good.  I've been disillusioned for some time with mainstream news and broadcasting networks and basically stopped reading and view them. Since then I've spent a great deal of time only reading technical blogs, but that is very dull and I needed something else.

Twitter has so far  giving me a broader aspect of the intraweb thingy and I've enjoyed it's simplicity and mostly it's breavity. Now, I suppose I can just go out and look up these things up for myself, and I'm not just about to stop doing that, but this way I can get information and opinions from people I feel like I can trust; even if those people get some of their information from the mainstream. :)

I've also add &lt;a href="http://twitterfeed.com/"&gt;Twitterfeed&lt;/a&gt;, which promises to post a &lt;a href="http://tinyurl.com/"&gt;Tiny url&lt;/a&gt; of the latest posts of any blog feed onto my twitter page. And in a shameless way the first feed I've added has be my own blog.

Tweet Tweet Tweet...&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-8042955656156543422?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/8042955656156543422/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/08/tweet-tweet-tweet.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/8042955656156543422'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/8042955656156543422'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/08/tweet-tweet-tweet.html' title='Tweet Tweet Tweet'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-8119003077408889603</id><published>2009-07-22T11:36:00.001+01:00</published><updated>2009-07-22T11:52:39.782+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Sorting International Names</title><content type='html'>My current employer has data on companies from almost every country in the world; lots of lists of companies from the four corners of the planet.

When listing these companies in a select box it would be nice to have them sorted alphabetically. The problem is the standard approach to sorting would be to use a comparator or comparable interface.

This will return something like this.
&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;
A, B, C, E, d
&lt;/code&gt;&lt;/pre&gt; because the string compareTo looks at the int char value and capital E is a smaller number than lower case d and therefore comes before in a sort.

It gets even more complicated when you add names with accented characters from places like Sweden, like &lt;span style=""&gt;&lt;span style="text-align: left;"&gt;å&lt;/span&gt;&lt;/span&gt;. &lt;span style=""&gt;&lt;span style="text-align: left;"&gt;å int value is much higher than standard A-Z and a-z and therefore comes after both upper and lower case letters.&lt;/span&gt;&lt;/span&gt;

Step up to the plate, &lt;a href="http://java.sun.com/javase/6/docs/api/java/text/Collator.html"&gt;java.text.Collator&lt;/a&gt;. This little class understands your pain. But more importantly it understands language. It can perform locale-sensitive string comparison.

What that means is the sorted list would be&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;
A, B, C, d, E
A, å, B, C, d, E
&lt;/code&gt;&lt;/pre&gt;...if you want it to be. It has the ability to sort upper and lower case with the same strength amoung other cool features.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-8119003077408889603?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/8119003077408889603/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/07/sorting-international-names.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/8119003077408889603'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/8119003077408889603'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/07/sorting-international-names.html' title='Sorting International Names'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-7249315434546638298</id><published>2009-06-30T13:47:00.000+01:00</published><updated>2009-06-30T13:50:23.816+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>The problem with Java Generics is.... (Redux)</title><content type='html'>...while pair programming...

bill &gt; Hey, we could use generics here.

bob  &gt; Great, why don't you drive.

bill &gt; Sure. What we need is a T here. Replace that return with T. Add another T here, and there you go. We can now use this for all types of things. Compile...check. Great. Let's fire up jetty.

bob  &gt; Hey, what does that mean?

bill &gt; Strange...it compiled ok. Oh! No problem. What we need is to add a ? here, then extends that to type T and that should work.

bob  &gt; Nope!!

bill &gt; Right, if move that ? to here, then use super of not extends, add T here that will work.

bob  &gt; Sorry, still not happy.

bill &gt; Really? But that's it? You have a T, and ?, the word extends or super. Damn!

bob &gt; Why not use instanceof? 

bill &gt; You can't because of erasure!

bob  &gt; Erasure? The electronic group from the 80s....I kind of liked them. 
&amp;#9834;I tried to discover...A little something to make me sweeter...&amp;#9834;

bill &gt; Stop that!! 

bob &gt; Sorry.

bill &gt; No, Type Erasure. When a generic type is instantiated, the compiler translates those types by a technique called type erasure — a process where the compiler removes all information related to type parameters and type arguments within a class or method.

bob &gt; Why would you do that?

bill &gt; Two words. Backwards compatibility.

bob &gt; That's doesn't help us.

bill &gt; Welcome to Generics in Java.

bob &gt; I knew we should have written this in Ruby!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-7249315434546638298?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/7249315434546638298/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/06/problem-with-java-generics-is-redux.html#comment-form' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/7249315434546638298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/7249315434546638298'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/06/problem-with-java-generics-is-redux.html' title='The problem with Java Generics is.... (Redux)'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-7547244272434753062</id><published>2009-06-25T15:45:00.000+01:00</published><updated>2009-06-25T15:50:48.072+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>JSON, do you have an invalid label error?</title><content type='html'>Invalid label error while evaluating a JSON_String?

Add parenthesis around the string and you'll be good to go.

&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;var myOject = eval('(' + JSON_String + ')');

&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-7547244272434753062?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/7547244272434753062/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/06/json-do-you-have-invalid-label-error.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/7547244272434753062'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/7547244272434753062'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/06/json-do-you-have-invalid-label-error.html' title='JSON, do you have an invalid label error?'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-7191704404021471559</id><published>2009-06-25T13:10:00.000+01:00</published><updated>2009-06-25T13:13:59.118+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>The problem with Java Generics is....</title><content type='html'>Fucking, fucker, focker, bullshit, piece of shit....fucking, fuckity, fuck! I'm going to .NET.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-7191704404021471559?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/7191704404021471559/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/06/problem-with-java-generics-is.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/7191704404021471559'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/7191704404021471559'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/06/problem-with-java-generics-is.html' title='The problem with Java Generics is....'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-7703899830326683545</id><published>2009-06-19T12:16:00.001+01:00</published><updated>2009-07-22T11:51:59.354+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Maven'/><title type='text'>Suppress Maven Profiles Via Command Line</title><content type='html'>Say you have an active development.profile with, for example, database settings. To change this in versions of maven older than 2.10, you would have to change where you defined your active profiles. (settings.xml, pom.xml, or profiles.xml)

However, with maven 2.10 and onwards you can use the minus symbol ( - ) to suppress your active profiles on the command line.

This is handy if you want to, for example again, run jetty:run against a different environment.

&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:Andale Mono,Lucida Console,Monaco,fixed,monospace;font-size:12px;"&gt;&lt;code&gt;mvn -Pstaging.profile,&lt;span style="color: rgb(255, 0, 0);font-size:130%;" &gt;&lt;span style="font-weight: bold;"&gt;-&lt;/span&gt;&lt;/span&gt;development.profile jetty:run
&lt;/code&gt;&lt;/pre&gt;This suppresses my active development.profile and activates my staging.profile&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-7703899830326683545?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/7703899830326683545/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/06/suppress-maven-profiles-via-command.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/7703899830326683545'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/7703899830326683545'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/06/suppress-maven-profiles-via-command.html' title='Suppress Maven Profiles Via Command Line'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-8136260498980465936</id><published>2009-05-07T11:21:00.000+01:00</published><updated>2009-05-07T13:04:11.377+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Craftsmanship'/><title type='text'>Schema Translation For Quick InMemory Integration Tests</title><content type='html'>In a &lt;a href="http://domfarr.blogspot.com/2009/04/too-much-time-wasted-running-tests.html"&gt;previous post&lt;/a&gt;, I highlighted the time wasted waiting for integration tests to run against a full database. I proposed the idea of running integration tests against an InMemory database locally and a full database in CI.  These are the steps I did to achieve this goal.

&lt;ul&gt;&lt;li&gt;Creation of unitils.dbmaintainer.script.ScriptSource classes&lt;/li&gt;&lt;li&gt;Transform schema files using regular expression&lt;/li&gt;&lt;li&gt;Configured Unitils.properties&lt;/li&gt;&lt;li&gt;Reconfigure the JpaVendorAdapter&lt;/li&gt;&lt;li&gt;Use Number for queries that use count&lt;/li&gt;&lt;/ul&gt;
&lt;h3&gt;ScriptSource Classes&lt;/h3&gt;Unitils' default ScriptSource implementation uses the file system to load schema files. I found this annoying because I would have to configure the location of the schema files with a full path. As this project is maven based and shared between a team, full paths are pointless unless you force the team to check out in exactly the same place.

Therefore I created my own version of &lt;a href="http://www.unitils.org/apidocs/org/unitils/dbmaintainer/script/impl/DefaultScriptSource.html"&gt;DefaultScriptSource&lt;/a&gt;, where the schema files are loaded using the Spring &lt;a href="http://static.springframework.org/spring/docs/2.5.x/api/org/springframework/core/io/DefaultResourceLoader.html"&gt;DefaultResourceLoaded&lt;/a&gt;. That way I can use the classpath prefix in the unitils.properties file.

Another addition to the ScriptSource implementation was preprocess method to translate schema from one database type to another. This method is called in the createScript method, just before the Script class is created.

&lt;pre   style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); line-height: 14px; width: 100%;font-family:onload;font-size:12px;"&gt;&lt;code&gt;protected Script createScript(List&lt;long&gt; parentIndexes, File scriptFile) {
...
String preprocessedScriptContent = &lt;span style="font-weight: bold;"&gt;preprocess(scriptContent)&lt;/span&gt;;
return new Script(scriptFile.getName(), preprocessedScriptContent, version);
}
&lt;/long&gt;&lt;/code&gt;&lt;/pre&gt;
Next I extended my version of the DefaultScriptSource class, overriding the preprocessor method. I called this new class, MySqlToHyperSonicAdaptingClasspathScriptSource, for want of a better name!  The preprocess method uses regular expressions to translate the schema from MySQL into HSQLDB statements.

&lt;h3&gt;Transform schema files&lt;/h3&gt;There are many differences between MySQL and HSQLDB statements and I didn't do a complete transformation. I only did the following.
&lt;ul&gt;&lt;li&gt;int sizes removed&lt;/li&gt;&lt;li&gt;bit sizes removed
&lt;/li&gt;&lt;li&gt;unsigned removed&lt;/li&gt;&lt;li&gt;long blob replaced with object&lt;/li&gt;&lt;li&gt;modify to alter column&lt;/li&gt;&lt;li&gt;engine statement removed&lt;/li&gt;&lt;li&gt;foreign key  checks removed&lt;/li&gt;&lt;li&gt;reordering of default values&lt;/li&gt;&lt;li&gt; removed quoted reserved words&lt;/li&gt;&lt;li&gt;change column to rename column
&lt;/li&gt;&lt;/ul&gt;&lt;h3&gt;Unitils.properties&lt;/h3&gt;This is the checked in unitils.properties file, the version the local integration tests use.
&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;org.unitils.dbmaintainer.script.ScriptSource.implClassName=domfarr.unitils.script.&lt;/code&gt;MySqlToHyperSonicAdaptingClasspathScriptSource
&lt;code&gt;dbMaintainer.script.locations=classpath:/database/schema
dbMaintainer.generateDataSetStructure.enabled=false
dbMaintainer.fromScratch.enabled=true
dbMaintainer.dbVersionSource.autoCreateVersionTable=true
dbMaintainer.autoCreateExecutedScriptsTable=true
DatabaseModule.Transactional.value.default=commit
updateDataBaseSchema.enabled=true
jpa.persistenceProvider=hibernate

database.dialect=hsqldb
database.driverClassName=org.hsqldb.jdbcDriver
database.url=jdbc:hsqldb:mem:aname
database.userName=sa
database.password=
database.schemaNames=PUBLIC

# Add this file in your home directory for custom db settings
&lt;span style="font-weight: bold; color: rgb(255, 0, 0);"&gt;unitils.configuration.localFileName=unitils.properties&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
The last line is important. This line loads another unitils.properties file located in the users.home directory. Any values in this file override any previous values configured. Locally you do not have this file, it is not checked in, and is outside of the project. However, the CI machine does have this file and it overrides to configure a MySQL database. It also uses my own version of DefaultScriptSource which does not preprocess the schema files.&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;database.driverClassName=com.mysql.jdbc.Driver
database.dialect=mysql
database.url=jdbc:mysql://123.123.123.123/bamboo
database.userName=bamboo
database.password=bamboo
database.schemaNames=bamboo
org.unitils.dbmaintainer.script.ScriptSource.implClassName=domfarr.unitils.script.ClasspathScriptSourceocessedScriptContent, version);
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;JpaVendorAdapter&lt;/h3&gt;When configuring the JpaVendorAdapter, I use spring, it asks for the dialect. Remove this entry, this basically works without it and you don't have to worry about filtering this file using maven.

&lt;h3&gt;Queries that use count&lt;/h3&gt;If you have a createNativeQuery that uses count, for example:&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;select count(distinct id) from companies inner join companies_relations on companies.id = companies_relations.parent_id"
&lt;/code&gt;&lt;/pre&gt;
Don't return the database specific class. MySQL returns BigInteger, HSQLDB returns Integer, return Number, the super class.&lt;pre style="border: 1px dashed rgb(153, 153, 153); padding: 5px; overflow: auto; font-family: Andale Mono,Lucida Console,Monaco,fixed,monospace; color: rgb(0, 0, 0); background-color: rgb(238, 238, 238); font-size: 12px; line-height: 14px; width: 100%;"&gt;&lt;code&gt;  public int size() {

int count = (Integer) getJpaTemplate().execute( new JpaCallback() {
  public Object doInJpa(EntityManager em) throws PersistenceException {

    Number count = (Number) em.createNativeQuery(
        "select count(distinct id) from companies inner join companies_relations " +
        "on companies.id = companies_relations.parent_id").getSingleResult();

    return count.intValue();

  }
} );

return count;
}
&lt;/code&gt;&lt;/pre&gt;
Okay...did you make it this far?  If you did, nice work. This post is way longer than I wanted, but I hope it works for you. If not let me know and I'll do my best to help out.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-8136260498980465936?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/8136260498980465936/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/05/schema-translation-for-quick-inmemory.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/8136260498980465936'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/8136260498980465936'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/05/schema-translation-for-quick-inmemory.html' title='Schema Translation For Quick InMemory Integration Tests'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-6704174076489263483</id><published>2009-05-06T11:07:00.000+01:00</published><updated>2009-05-06T11:14:44.545+01:00</updated><title type='text'>Rod Bobble Head</title><content type='html'>When this book came out, the image on the cover was a common topic after a few beers. 

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_85PE35NneMI/SgFitySlE1I/AAAAAAAAAEo/gAOaS8yH1iQ/s1600-h/rod.bmp"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 154px; height: 181px;" src="http://4.bp.blogspot.com/_85PE35NneMI/SgFitySlE1I/AAAAAAAAAEo/gAOaS8yH1iQ/s320/rod.bmp" border="0" alt=""id="BLOGGER_PHOTO_ID_5332651972516713298" /&gt;&lt;/a&gt;


Things have now come full circle with the release of the bobble head.

&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_85PE35NneMI/SgFiWFTv0qI/AAAAAAAAAEg/miRqmYsXLJA/s1600-h/SpringOneEurope2009DayThreeBobblehead.JPG"&gt;&lt;img style="cursor:pointer; cursor:hand;width: 300px; height: 203px;" src="http://3.bp.blogspot.com/_85PE35NneMI/SgFiWFTv0qI/AAAAAAAAAEg/miRqmYsXLJA/s320/SpringOneEurope2009DayThreeBobblehead.JPG" border="0" alt=""id="BLOGGER_PHOTO_ID_5332651565305025186" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-6704174076489263483?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/6704174076489263483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/05/rod-bobble-head.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/6704174076489263483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/6704174076489263483'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/05/rod-bobble-head.html' title='Rod Bobble Head'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_85PE35NneMI/SgFitySlE1I/AAAAAAAAAEo/gAOaS8yH1iQ/s72-c/rod.bmp' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-4219234197486996458</id><published>2009-04-17T15:20:00.000+01:00</published><updated>2009-04-17T16:43:50.239+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Craftsmanship'/><title type='text'>Too Much Time Wasted Running Tests</title><content type='html'>When I arrived at my current project, it had a large stack of integration tests using a combination of Spring, Hibernate, DbUnit and Unitils. The test suite was backed by MySql in all environments. (local, CI and Production.)

The problem with this solution is time! It takes anywhere from 3 to 4 minutes to execute mvn clean test on our dev boxes. Now, that does sound like a long time to wait, and I've worked on projects that have taken over 15 minutes to complete the test suite, but it adds up.

Multiple that time by the number of times a day a developer runs the test suite, times that by the number of developers on the team, and you start to get serious amounts of time spinning your wheels. 

I conservatively estimated the team as a whole was waiting over 3 hours a day for the test suite to complete. 

Beyond these numbers, we use TDD and it is good development practice to check in as often as you can. If the time taken to run your test suite hinders that, you are already slipping into the dark.

I set about finding a solution; looking around, asking some questions and some scratching of heads these two options were selected.

&lt;ul&gt;&lt;li&gt;Split off the long running integration tests and have them only run under a specific maven profile&lt;/li&gt;&lt;li&gt;Use a faster in-memory database like HSQLDB or H2&lt;/li&gt;&lt;/ul&gt;
Splitting off the longer integration tests does allow the developer to run their tests quicker, but they have to wait for CI to catch any integration test failings. This means if there are errors with integration that code as been checked in. Checked in code that has errors...err. no!

Changing to an in-memory database means your schema definition has to change because it will inevitably contain database specific elements. Furthermore, you are no longer using the same database as your production environment, and therefore more testing will have to be done to ensure there are no gotchas when deploying to production due to database change.

Neither option sat well with us, so we opted for a combination.
Run all tests against an in-memory database in development, but have CI run against a production like database.

With this option you get the fast, full test suite locally, and have CI deal with the longer wait that comes with using a production like database.  Of course, there is the chance that your CI will still fail, but the likelihood is much lower.

How this was actually achieved will be in my next post. This will include how I overcame schema difference without duplication; dialect issues and handling return type class issues from different database drivers.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-4219234197486996458?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/4219234197486996458/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/04/too-much-time-wasted-running-tests.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/4219234197486996458'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/4219234197486996458'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/04/too-much-time-wasted-running-tests.html' title='Too Much Time Wasted Running Tests'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-5210300680833619217</id><published>2009-04-13T12:32:00.000+01:00</published><updated>2009-04-13T14:26:01.995+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tapestry 5'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>Tapestry 5 PageTester with Spring Managed Beans</title><content type='html'>In pursuit of better test coverage I have been looking into the Tapestry 5 &lt;a href="http://tapestry.apache.org/tapestry5.1/apidocs/org/apache/tapestry5/test/PageTester.html"&gt;PageTester&lt;/a&gt;. 

However, if you have services that are managed by Spring your pages that have these services injected will run into problems.

In a normal Tapestry 5 app that using Spring managed beans the Spring context is loaded via the web ContextLoaderListener.  These beans are then picked up by the Tapestry IOC for injecting into your pages. 

The PageTester doesn't perform this Spring context loading and therefore your injected services will be null. Furthermore, I'm only looking at unit testing here, so I don't want to fire up a bunch of integration type objects. For integration testing look at &lt;a href="http://www.jitr.org/"&gt;jitr.org&lt;/a&gt; 

A solution to the lack of Spring beans was to use a TestAppModule class that binds mock services for the PageTester to use.
&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;new PageTester(&amp;quot;domfarr.web.tapestry&amp;quot;, &amp;quot;&amp;quot;,
        &amp;quot;src/main/webapp&amp;quot;, &lt;strong&gt;TestAppModule.class&lt;/strong&gt;);
&lt;/code&gt;&lt;/pre&gt;
TestAppModule class looks like this.
&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;  public static class TestAppModule {
    public static ContactService buildContactService() {
      return mock(ContactService.class);
    }
  }
&lt;/code&gt;&lt;/pre&gt;
I use &lt;a href="http://mockito.org/"&gt;Mockito &lt;/a&gt;as my mocking framework.

The PageTester uses the TestAppModule to register my mock contact service and inject it into my page, and the tests have access to the contact service mock object by calling getService("ContactService") on the PageTester's registry.
&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;  @Test
  public void testContactForm() {
    setupMockStubCalls();
    
    Element contactAddForm = startPage.getElementById(&amp;quot;form&amp;quot;);

    Map&amp;lt;String, String&amp;gt; formValues = new HashMap&amp;lt;String, String&amp;gt;();
    formValues.put(&amp;quot;phoneNumber&amp;quot;, &amp;quot;555-1234&amp;quot;);
    formValues.put(&amp;quot;fullName&amp;quot;, &amp;quot;Dom Farr&amp;quot;);
    
    Document submissionReturnDocument = pageTester.submitForm(
        contactAddForm, formValues);

    Element pageMessage = submissionReturnDocument
        .getElementById(&amp;quot;message&amp;quot;);

    assertThat(pageMessage.getChildMarkup(),
        equalTo(&amp;quot;Contact Dom Farr Added Successfully&amp;quot;));
  }

  private void setupMockStubCalls() {
    ContactService mockContactService = &lt;strong&gt;pageTester.getRegistry().getService(ContactService.class);&lt;/strong&gt;
    
    Contact contact = new Contact();
    contact.setFullName(&amp;quot;Dom Farr&amp;quot;);
    contact.setPhoneNumber(&amp;quot;555-1234&amp;quot;);
    when(mockContactService.save(contact).thenReturn(contact);
  }
&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-5210300680833619217?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/5210300680833619217/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/04/tapestry-5-pagetester-with-spring.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/5210300680833619217'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/5210300680833619217'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/04/tapestry-5-pagetester-with-spring.html' title='Tapestry 5 PageTester with Spring Managed Beans'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-1844703264932585119</id><published>2009-04-11T15:30:00.000+01:00</published><updated>2009-04-13T12:36:31.492+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tapestry 5'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><title type='text'>PageTester SerializationSupport Error</title><content type='html'>Using the Tapestry 5 &lt;a href="http://tapestry.apache.org/tapestry5.1/apidocs/org/apache/tapestry5/test/PageTester.html"&gt;PageTester&lt;/a&gt; in your unit tests you will need to add a method to shut it down after each test. If you don't you will get this error.

&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;ERROR SerializationSupport - 
Setting a new service proxy provider when there's already an existing provider. 
This may indicate that you have multiple IoC Registries.
&lt;/code&gt;&lt;/pre&gt;
For example.
&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;@Before
public void context() {
  pageTester = new PageTester(&amp;quot;tapestry&amp;quot;,&amp;quot;app&amp;quot;, &amp;quot;src/main/webapp&amp;quot;);
}
  
@After
public void tearDown() {
  pageTester.shutdown();
}

@Test
public void testStartPage() {
  startPage = pageTester.renderPage(&amp;quot;Start&amp;quot;);
  assertThat(startPage.getElementById(&amp;quot;message&amp;quot;).getChildMarkup(), equalTo(&amp;quot;Hello&amp;quot;));
}
&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-1844703264932585119?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/1844703264932585119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/04/pagetester-serializationsupport-error.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/1844703264932585119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/1844703264932585119'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/04/pagetester-serializationsupport-error.html' title='PageTester SerializationSupport Error'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-3210364328997115015</id><published>2009-04-10T15:41:00.000+01:00</published><updated>2009-04-13T13:48:40.088+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tapestry 5'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Maven'/><title type='text'>Surefire plugin, JUnit annotations and Tapestry 5 PageTester</title><content type='html'>Tapestry 5 has a nice &lt;a href="http://tapestry.apache.org/tapestry5/tapestry-core/guide/unit-testing-pages.html"&gt;testing framework&lt;/a&gt; which allows you to test your pages and components without the need to fire up a servlet container and do expensive integration tests.

If you want to use maven test and junit 4 annotations then you will need to exclude the testng dependency.

&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&amp;lt;dependency&amp;gt;
  &amp;lt;groupId&amp;gt;org.apache.tapestry&amp;lt;/groupId&amp;gt;
  &amp;lt;artifactId&amp;gt;tapestry-test&amp;lt;/artifactId&amp;gt;
  &amp;lt;version&amp;gt;${tapestry.version}&amp;lt;/version&amp;gt;
  &amp;lt;scope&amp;gt;test&amp;lt;/scope&amp;gt;
  &amp;lt;exclusions&amp;gt;
    &amp;lt;exclusion&amp;gt;
      &amp;lt;groupId&amp;gt;org.testng&amp;lt;/groupId&amp;gt;
      &amp;lt;artifactId&amp;gt;testng&amp;lt;/artifactId&amp;gt;
    &amp;lt;/exclusion&amp;gt;
  &amp;lt;/exclusions&amp;gt;
&amp;lt;/dependency&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
Without this exclusion, the surefire plugin fails to see your JUnit tests that are annotated with @Test.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-3210364328997115015?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/3210364328997115015/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/04/surefire-plugin-junit-annotations-and.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/3210364328997115015'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/3210364328997115015'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/04/surefire-plugin-junit-annotations-and.html' title='Surefire plugin, JUnit annotations and Tapestry 5 PageTester'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-1754627436493779021</id><published>2009-04-02T14:29:00.000+01:00</published><updated>2009-04-02T14:41:00.501+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Tapestry 5'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Tapestry 5 if else condition</title><content type='html'>You may at some point need to have simple conditions in your tapestry view. 

Tapestry 5.1 use this version

&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&amp;lt;html xmlns:t=&amp;quot;http://tapestry.apache.org/schema/tapestry_5_1_0.xsd&amp;quot; xmlns:p=&amp;quot;tapestry:parameter&amp;quot;&amp;gt;
&amp;lt;t:if test=&amp;quot;loggedIn&amp;quot;&amp;gt;
  Hello, ${userName}!
  &amp;lt;p:else&amp;gt;
    Click &amp;lt;a t:type=&amp;quot;actionlink&amp;quot; t:id=&amp;quot;login&amp;quot;&amp;gt;here&amp;lt;/a&amp;gt; to log in.
  &amp;lt;/p:else&amp;gt;
&amp;lt;/t:if&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
Older versions of Tapestry 5 use this version

&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;&lt;strong&gt;&amp;lt;html xmlns:t=&amp;quot;http://tapestry.apache.org/schema/tapestry_5_1_0.xsd&amp;quot;&amp;gt;&lt;/strong&gt;
&amp;lt;t:if test=&amp;quot;loggedIn&amp;quot;&amp;gt;
  Hello, ${userName}!
  &lt;strong&gt;&amp;lt;t:parameter name=&amp;quot;else&amp;quot;&amp;gt;&lt;/strong&gt;
    Click &amp;lt;a t:type=&amp;quot;actionlink&amp;quot; t:id=&amp;quot;login&amp;quot;&amp;gt;here&amp;lt;/a&amp;gt; to log in.
  &lt;strong&gt;&amp;lt;/t:parameter&amp;gt;&lt;/strong&gt;
&amp;lt;/t:if&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-1754627436493779021?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/1754627436493779021/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/04/tapestry-5-if-else-condition.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/1754627436493779021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/1754627436493779021'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/04/tapestry-5-if-else-condition.html' title='Tapestry 5 if else condition'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-1077963619018062081</id><published>2009-04-01T15:45:00.000+01:00</published><updated>2009-04-01T16:09:44.203+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>Remove Item From Collection</title><content type='html'>If you directly remove from an item from a collection you will trigger a java.util.ConcurrentModificationException

&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;
Collection&amp;lt;String&amp;gt; mySet = new HashSet&amp;lt;String&amp;gt;();
mySet.add(&amp;quot;one&amp;quot;);
mySet.add(&amp;quot;two&amp;quot;);
mySet.add(&amp;quot;three&amp;quot;);
mySet.add(&amp;quot;four&amp;quot;);

for (String item : mySet) {
  if (item.startsWith(&amp;quot;t&amp;quot;)) {
    mySet.remove(item);
  }
}

System.out.println(mySet);
&lt;/code&gt;&lt;/pre&gt;
Which will give this. 
&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;
Exception in thread "main" java.util.ConcurrentModificationException
 at java.util.HashMap$HashIterator.nextEntry(Unknown Source)
 at java.util.HashMap$KeyIterator.next(Unknown Source)
&lt;/code&gt;&lt;/pre&gt;


For years, when I had a collection and I wanted to remove a number of items from it I used this pattern.

&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;
Collection&amp;lt;String&amp;gt; mySet = new HashSet&amp;lt;String&amp;gt;();
mySet.add(&amp;quot;one&amp;quot;);
mySet.add(&amp;quot;two&amp;quot;);
mySet.add(&amp;quot;three&amp;quot;);
mySet.add(&amp;quot;four&amp;quot;);

Collection&amp;lt;String&amp;gt; toBeRemoved = new HashSet&amp;lt;String&amp;gt;();

for (String item : mySet) {
  if (item.startsWith(&amp;quot;t&amp;quot;)) {
    toBeRemoved.add(item);
  }
}

mySet.removeAll(toBeRemoved);

System.out.println(mySet);
&lt;/code&gt;&lt;/pre&gt;
Which will give this. 
&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;[one, four]
&lt;/code&gt;&lt;/pre&gt;

I never really like this and today I bothered to look beyond my nose and found you can remove without the need for the toBeRemoved Collection by using an Iterator and its remove method.

&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;
&lt;code&gt;
  Collection&amp;lt;String&amp;gt; mySet = new HashSet&amp;lt;String&amp;gt;();
  mySet.add(&amp;quot;one&amp;quot;);
  mySet.add(&amp;quot;two&amp;quot;);
  mySet.add(&amp;quot;three&amp;quot;);
  mySet.add(&amp;quot;four&amp;quot;);

  Iterator&amp;lt;String&amp;gt; iterator = mySet.iterator();
    
  while(iterator.hasNext()) {
    String item = iterator.next();
    if (item.startsWith(&amp;quot;t&amp;quot;)) {
      &lt;strong&gt;iterator&lt;/strong&gt;.remove();
    }
  }

  System.out.println(mySet);
&lt;/code&gt;&lt;/pre&gt;


This one I like, no need for that silly extra collection object.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-1077963619018062081?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/1077963619018062081/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/04/remove-item-from-collection.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/1077963619018062081'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/1077963619018062081'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/04/remove-item-from-collection.html' title='Remove Item From Collection'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-8482800312532905583</id><published>2009-03-31T13:27:00.000+01:00</published><updated>2009-03-31T21:30:53.027+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dev Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><title type='text'>Git: You're ugle and stupid if you use anything else</title><content type='html'>Source control has been a source of pain in every project I've ever contributed to.

In my time I've used CVS, SVN and Visual SourceSafe. CVS seemed okay until there were conflicts or you wanted to delete something. SVN kind of corrected some of the CVS issues, but merging and branching were still a real headache. And I'm going to skip VSS because I don't want to write nasty words in this blog.

There are other issues as well. It is very hard to work offline; you can't check code in if it breaks the test suite because it will break everyone else; history of refactors that involve multi files are lost.

&lt;a href="http://en.wikipedia.org/wiki/Git_(software)"&gt;Git&lt;/a&gt; might be the answer. It's from Mr Linux himself so it has good heritage. I found this talk he gave at Google about Git and how you are ugle and stupid if you use anything else. 

As ever, Linus Torvalds is full of bright ideas, brutal critism of other software and the people that write it, very high priase for himself, and all said with a tongue-in-cheek humour. But strip away the irreverent humour and he has solid points. 

&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/4XpnKHJAok8&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;param name="allowscriptaccess" value="always"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/4XpnKHJAok8&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;

(yes - I know - this is two years old - what can you do, eh)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-8482800312532905583?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/8482800312532905583/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/03/git-youre-ugle-and-stupid-if-you-use.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/8482800312532905583'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/8482800312532905583'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/03/git-youre-ugle-and-stupid-if-you-use.html' title='Git: You&apos;re ugle and stupid if you use anything else'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-5936402092330085446</id><published>2009-01-09T14:11:00.000Z</published><updated>2009-01-09T14:27:39.566Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>When is an ArrayList NOT an ArrayList....</title><content type='html'>....when you use Arrays.asList(T... a)

JavaDoc says:
&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;List stooges = Arrays.asList(&amp;quot;Larry&amp;quot;, &amp;quot;Moe&amp;quot;, &amp;quot;Curly&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;

Would it be reasonable to do this?
&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;ArrayList stooges = (ArrayList) Arrays.asList(&amp;quot;Larry&amp;quot;, &amp;quot;Moe&amp;quot;, &amp;quot;Curly&amp;quot;);
&lt;/code&gt;&lt;/pre&gt;

&lt;span style="font-weight:bold;"&gt;Computer says no!&lt;/span&gt;  Why? 
Arrays.asList uses a internally reimplements of ArrayList.
&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;private static class ArrayList&lt;e&gt; extends AbstractList&lt;e&gt;
&lt;/code&gt;&lt;/pre&gt;

Whatever happened to not reinventing the wheel!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-5936402092330085446?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/5936402092330085446/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/01/when-is-arraylist-not-arraylist.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/5936402092330085446'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/5936402092330085446'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/01/when-is-arraylist-not-arraylist.html' title='When is an ArrayList NOT an ArrayList....'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-865984426248148899</id><published>2009-01-06T19:45:00.001Z</published><updated>2009-01-09T14:28:05.587Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>Code Review</title><content type='html'>&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_85PE35NneMI/SWO1DnHwfMI/AAAAAAAAAEA/6m8UFTrWsAo/s1600-h/codeReview.JPG"&gt;&lt;img style="cursor: pointer; width: 320px; height: 299px;" src="http://4.bp.blogspot.com/_85PE35NneMI/SWO1DnHwfMI/AAAAAAAAAEA/6m8UFTrWsAo/s320/codeReview.JPG" alt="" id="BLOGGER_PHOTO_ID_5288269461108849858" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-865984426248148899?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/865984426248148899/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2009/01/code-review.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/865984426248148899'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/865984426248148899'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2009/01/code-review.html' title='Code Review'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_85PE35NneMI/SWO1DnHwfMI/AAAAAAAAAEA/6m8UFTrWsAo/s72-c/codeReview.JPG' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-4046365511579874054</id><published>2008-09-18T18:07:00.000+01:00</published><updated>2008-09-18T18:20:55.906+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='General'/><title type='text'>All change</title><content type='html'>Just a quick post. Apologies to my small and faithful readership that I've not posted recently. 

I am moving back to the UK after 9 years of the wonderful Canadian lifestyle and time is a rare resource right now.

I will continue posting while I'm in England and I hope you continue reading and sharing my posts.

I'll be back in the UK as of October the 16th, 2008 and will start posting then.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-4046365511579874054?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/4046365511579874054/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2008/09/all-change.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/4046365511579874054'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/4046365511579874054'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2008/09/all-change.html' title='All change'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-8425706356561344477</id><published>2008-09-10T02:35:00.000+01:00</published><updated>2008-09-10T02:46:39.548+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Random Tech'/><title type='text'>Free Geek</title><content type='html'>I stumbled across this recently. &lt;a href="http://freegeekvancouver.org"&gt;http://freegeekvancouver.org&lt;/a&gt; 

Next time you have or hear about a computer that just isn't worth saving, remember these guys and help out.

If you want to skip the reading and watch the video.  Here it is.

&lt;object width="425" height="344"&gt;&lt;param name="movie" value="http://www.youtube.com/v/625LPUACix0&amp;hl=en&amp;fs=1"&gt;&lt;/param&gt;&lt;param name="allowFullScreen" value="true"&gt;&lt;/param&gt;&lt;embed src="http://www.youtube.com/v/625LPUACix0&amp;hl=en&amp;fs=1" type="application/x-shockwave-flash" allowfullscreen="true" width="425" height="344"&gt;&lt;/embed&gt;&lt;/object&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-8425706356561344477?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/8425706356561344477/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2008/09/free-geek.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/8425706356561344477'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/8425706356561344477'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2008/09/free-geek.html' title='Free Geek'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-1446978257614238607</id><published>2008-09-04T19:12:00.000+01:00</published><updated>2008-09-04T19:21:07.697+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='WebFlow'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Pair Programming Saves The Day.</title><content type='html'>With some good pair programming the new version of Spring IDE (2.1) was released with support for Spring Web Flow 2.0.3.

Read Christian Dupuis blog for full story.
&lt;a href="http://springide.org/blog/2008/08/01/21-with-web-flow-2-support-released/"&gt;21-with-web-flow-2-support-released&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-1446978257614238607?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/1446978257614238607/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2008/09/pair-programming-saves-day.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/1446978257614238607'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/1446978257614238607'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2008/09/pair-programming-saves-day.html' title='Pair Programming Saves The Day.'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-4586191963416048543</id><published>2008-08-27T17:51:00.000+01:00</published><updated>2008-08-27T22:12:14.671+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dev Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Craftsmanship'/><category scheme='http://www.blogger.com/atom/ns#' term='Fear'/><title type='text'>Code block formatter for your blog</title><content type='html'>You may have notice that the code blocks in my blog entries are nicely formatted and have a snazzy grey box around them. 

&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;package domfarr;

public final class HelloWorld {
  public static void main(String[] args) {
    System.out.println(&amp;quot;Hello World!&amp;quot;);
  }
}
&lt;/code&gt;&lt;/pre&gt;

How do I do them you ask? A god like knowledge of JavaScript and CSS! Well, no. As any pragmatic developer does, I check to see if someone had already invented the wheel.

And they have:
&lt;a href="http://formatmysourcecode.blogspot.com/2006/02/paste-your-text-here.html#links"&gt;Format My Source Code for Blogging&lt;/a&gt;

&lt;span style="font-weight:bold;color:red"&gt;Remember, someone is always listening. So make your code generic. We don't want your company or client getting all upset because you just posted their new encryption string.&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-4586191963416048543?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/4586191963416048543/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2008/08/code-block-formatter-for-your-blog.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/4586191963416048543'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/4586191963416048543'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2008/08/code-block-formatter-for-your-blog.html' title='Code block formatter for your blog'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-803850528690680142</id><published>2008-08-26T01:30:00.000+01:00</published><updated>2008-08-27T18:04:48.251+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Has Spring entered its Autumn?</title><content type='html'>I'm currently working on a new web based application using Spring's contract first style web services, some jpa and simple Spring MVC client. 

Up to now I've only used extension for web controllers, and mostly extending the SimpleFormController. But as this was a green field I can move up to Spring 2.5.x and with that start using annotated based pojos for my controllers.

This all started off really good, until I came to validation of the form. Previously you injected your validator and somewhere in the package hierarchy Spring would call the support method of the validator to make sure it was of the right type.

But to my horror using annotated controllers I have to call the support method manually. What happened to abstracting calls away from your implementation.

This the example of the 2.5.5 sample pet client application.

&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;  @RequestMapping(method = RequestMethod.POST)
  public String processSubmit(@ModelAttribute(&amp;quot;pet&amp;quot;) Pet pet, BindingResult result, SessionStatus status) {
&lt;span style="font-family:font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size:12px;font-style:normal;font-weight:bold;text-decoration:none;text-transform:none;color:red;background-color:ffffff;"&gt;    new PetValidator().validate(pet, result);&lt;/span&gt;
    if (result.hasErrors()) {
      return &amp;quot;petForm&amp;quot;;
    }
    else {
      this.clinic.storePet(pet);
      status.setComplete();
      return &amp;quot;redirect:owner.do?ownerId=&amp;quot; + pet.getOwner().getId();
    }
  }
&lt;/code&gt;&lt;/pre&gt;

No DI and no call to the support method!

Has Spring entered its autumn, will all the leaves be turning brown. I doubt it, Spring has a great many things to offer jee. However, Spring MVC is moving in the wrong direction right now and I hope it is corrected soon.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-803850528690680142?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/803850528690680142/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2008/08/has-spring-entered-its-autumn.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/803850528690680142'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/803850528690680142'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2008/08/has-spring-entered-its-autumn.html' title='Has Spring entered its Autumn?'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-3700438286845780229</id><published>2008-08-19T17:45:00.001+01:00</published><updated>2008-08-19T18:04:40.950+01:00</updated><title type='text'>Home and End keys in Eclipse IDE.</title><content type='html'>A quick follow up from previous bindings post.

There are always exceptions and Eclipse IDE is one of those.

If you want the same mappings for home and end keys for Eclipse you will have to change your Eclipse preferences.

Goto preferences-&gt;general-&gt;keys.

The only mappings that, in my opinion, are a little strange are top and bottom of the document. These mapping are called Text Start and Text End.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-3700438286845780229?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/3700438286845780229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2008/08/home-and-end-keys-in-eclipse-ide.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/3700438286845780229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/3700438286845780229'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2008/08/home-and-end-keys-in-eclipse-ide.html' title='Home and End keys in Eclipse IDE.'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-988133941820643694</id><published>2008-08-19T17:04:00.000+01:00</published><updated>2008-08-19T17:20:29.060+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dev Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Mac'/><title type='text'>Key Bindings For Mac</title><content type='html'>I use multiple OS and switching between then can sometimes drive me round the twist.

I'm sure that Apple and Microsoft do this on purpose, but that might be the paranoid android in side of me.

If you like your home and end keys to perform a full suite of functions, here are the mappings for Mac OS.

Create or edit, ~/Library/KeyBindings/DefaultKeyBinding.dict

Add the follow, and save the file.

&lt;pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"&gt;&lt;code&gt;{
&amp;quot;\UF729&amp;quot;  = &amp;quot;moveToBeginningOfLine:&amp;quot;;                   /* Home         */
&amp;quot;\UF72B&amp;quot;  = &amp;quot;moveToEndOfLine:&amp;quot;;                         /* End          */
&amp;quot;$\UF729&amp;quot; = &amp;quot;moveToBeginningOfLineAndModifySelection:&amp;quot;; /* Shift + Home */
&amp;quot;$\UF72B&amp;quot; = &amp;quot;moveToEndOfLineAndModifySelection:&amp;quot;;       /* Shift + End  */
&amp;quot;^\UF729&amp;quot; = &amp;quot;moveToBeginningOfDocument:&amp;quot;;               /* Ctrl + Home */
&amp;quot;^\UF72B&amp;quot; = &amp;quot;moveToEndOfDocument:&amp;quot;;                     /* Ctrl + End  */
}
&lt;/code&gt;&lt;/pre&gt;

For a full run down of key bindings, check out the &lt;a href="http://www.lsmason.com/articles/macosxkeybindings.html"&gt;Mac OS X Key Bindings&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-988133941820643694?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/988133941820643694/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2008/08/key-bindings-for-mac.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/988133941820643694'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/988133941820643694'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2008/08/key-bindings-for-mac.html' title='Key Bindings For Mac'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-1247596211818129670</id><published>2008-08-14T04:09:00.000+01:00</published><updated>2008-08-14T04:31:54.351+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Fear'/><title type='text'>Net Neutrality</title><content type='html'>&lt;a href="http://foureyedmonsters.com/neutrality/"&gt;An important message  - or - conspiracy theory
&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-1247596211818129670?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/1247596211818129670/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2008/08/net-neutrality.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/1247596211818129670'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/1247596211818129670'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2008/08/net-neutrality.html' title='Net Neutrality'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-574019339148008432</id><published>2008-08-11T18:37:00.000+01:00</published><updated>2008-08-11T18:54:34.889+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dev Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Maven'/><title type='text'>Maven Jetty plugin and security realms</title><content type='html'>I often use the &lt;a href="http://docs.codehaus.org/display/JETTY/Maven+Jetty+Plugin"&gt;Jetty plugin&lt;/a&gt; for Maven; it's a super way to speed up development.

I'm currently in the process of creating a new web application which will need some basic security. For completeness I wanted to add a security user realm to my jetty configuration.

I initially added the realm in Jetty configuration, per the Jetty manual instructions.

My realm.properties where being loaded, the Jetty configuration was also without error, but when the Jetty container fired up I get an unknown realm warning.

Much wailing and nashing of teeth later I moved the user realm to the pom plugin definition and all is good. Why it didn't work using the configuration file is still a mystery.

    &amp;lt;plugin&amp;gt;
         &amp;lt;groupId&amp;gt;org.mortbay.jetty&amp;lt;/groupId&amp;gt;
         &amp;lt;artifactId&amp;gt;maven-jetty-plugin&amp;lt;/artifactId&amp;gt;
      &amp;lt;version&amp;gt;6.1.10&amp;lt;/version&amp;gt;
      &amp;lt;configuration&amp;gt;
        &amp;lt;contextPath&amp;gt;/bmbo&amp;lt;/contextPath&amp;gt;
        &amp;lt;userRealms&amp;gt;
          &amp;lt;userRealm implementation="org.mortbay.jetty.security.HashUserRealm"&amp;gt;
            &amp;lt;name&amp;gt;Bonus Manager Realm&amp;lt;/name&amp;gt;
            &amp;lt;config&amp;gt;
              src/test/resources/jetty-realm.properties
            &amp;lt;/config&amp;gt;
          &amp;lt;/userRealm&amp;gt;
        &amp;lt;/userRealms&amp;gt;
      &amp;lt;/configuration&amp;gt;
    &amp;lt;/plugin&amp;gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-574019339148008432?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/574019339148008432/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2008/08/maven-jetty-plugin-and-security-realms.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/574019339148008432'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/574019339148008432'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2008/08/maven-jetty-plugin-and-security-realms.html' title='Maven Jetty plugin and security realms'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-379727093408217372</id><published>2008-08-10T00:19:00.000+01:00</published><updated>2008-08-10T00:25:51.906+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dev Tools'/><title type='text'>Using Textmate as you svn editor</title><content type='html'>When running the check in command for svn you have to supply the -m attribute and a string for the comment.

If you want to use your favourite editor, you must set an environment variable: SVN_EDITOR

If you are on mac and want to use TextMate, use the wait attribute.

eg. export SVN_EDITOR=’mate -w’&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-379727093408217372?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/379727093408217372/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2008/08/using-textmate-as-you-svn-editor.html#comment-form' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/379727093408217372'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/379727093408217372'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2008/08/using-textmate-as-you-svn-editor.html' title='Using Textmate as you svn editor'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-5912495283842356680</id><published>2008-08-10T00:03:00.000+01:00</published><updated>2008-08-14T19:38:16.779+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>Needs some space</title><content type='html'>If you are writing a jsp in xhtml you can't use normal xml entity references.
eg. &amp;bsnp;

This is because you can't set entity declarations, like this.

&amp;lt;!--ENTITY nbsp "&amp;amp;#160;" --&amp;gt;]&amp;gt;

You will have to do this.

&amp;amp;amp;nbsp;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-5912495283842356680?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/5912495283842356680/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2008/08/needs-some-space.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/5912495283842356680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/5912495283842356680'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2008/08/needs-some-space.html' title='Needs some space'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-2125846765365617061</id><published>2008-04-16T23:30:00.000+01:00</published><updated>2008-08-10T00:31:38.217+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dev Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><title type='text'>The hippest tool set</title><content type='html'>There is much talk about the hippest tool set at my current employer. And to be honest most of it is tongue in cheek. But enough about our sarcasm, here's a good read.

&lt;a href="http://www.artima.com/forums/flat.jsp?forum=276&amp;amp;thread=228921"&gt;&lt;span class="ts"&gt;Rod Johnson's Predictions for Enterprise Java&lt;/span&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-2125846765365617061?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/2125846765365617061/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2008/04/hippest-tool-set.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/2125846765365617061'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/2125846765365617061'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2008/04/hippest-tool-set.html' title='The hippest tool set'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-4263208224199149443</id><published>2007-12-06T23:25:00.000Z</published><updated>2008-08-10T00:26:36.530+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Multiple Forms And The SimpleFormController</title><content type='html'>&lt;p&gt;Some pages will inevitably contain multiple forms.  If you use the &lt;a href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/web/portlet/mvc/SimpleFormController.html" title="SimpleFormController API Doc" target="_blank"&gt;SimpleFormController&lt;/a&gt; from Spring, you will need to override the isFormSubmission method.&lt;/p&gt; &lt;p&gt;By default this controller makes the decision to call the onSubmit method by simply checking the request method. However, if there are multiple forms on the same page and another form posts, your controller needs to understand the post wasn’t for it and it shouldn’t call the onSubmit method.&lt;/p&gt; &lt;p&gt;Overriding the isFormSubmission method allows you to check that the request contains the correct form object. If the form object for the controller isn’t on the request, don’t call onSubmit.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-4263208224199149443?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/4263208224199149443/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2007/12/multiple-forms-and-simpleformcontroller.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/4263208224199149443'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/4263208224199149443'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2007/12/multiple-forms-and-simpleformcontroller.html' title='Multiple Forms And The SimpleFormController'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-4304091718112580535</id><published>2007-09-17T23:10:00.000+01:00</published><updated>2008-08-10T00:29:28.861+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Craftsmanship'/><title type='text'>Scott Ambler - Agile In The Real World</title><content type='html'>I was able the catch Scott Ambler speak at the IBM Burnaby office today.  It wasn't a long  talk, about 1 hour or so, but he packed in a great deal of information. Here are my notes.

&lt;h3&gt;Traditional Software Design&lt;/h3&gt;
Academics came up with a bunch of ideas that should work, a theory.
Traditional method of: Requirements, Analysis, Design, Program and Test methods mean that validation of the Requirements and Analysis isn't done until the Test phase. Which means that the guys doing the Requirements and Analysis have no clue of the damage until it is too late. Each step information is lost or misinterpreted.

The famous quote. Build software like building a bridge.

....but now we know differently.

&lt;h3&gt;Agile or Evolutionary method&lt;/h3&gt;
Agile is not theory, it is based on practice.
Less upfront documents. Tests = Specification.
High quality software delivered every iteration.
Scope creep is good! If you stop feature creep it means you are making software that the stakeholder doesn't want.

&lt;h3&gt;Success&lt;/h3&gt;
80% of stakeholders want what they need, not what the spec designed.
B.R.U.F. Leads to  Significant Wastage: 45% of features delivered were never used when designing with serial methods.
http://www.agilemodeling.com/essays/examiningBRUF.htm

Success is not "On time, on budget, to specification." Success is more about delivering quality software that the stakeholder wants today. Spending the money wisely.

Deliver working software frequently allows the stakeholders to continually gage the success of a project.

Documentation doesn't give value, only delivering working quality software does.

More collaboration == more success. White board things often with everyone.

Focus on quality...more testing = higher quality.

There is no silver bullet, agile requires skilled people.

&lt;h3&gt;Developers&lt;/h3&gt;
Developers should move away from specialization. It isn't effective.

Being a specialist means having to hand off things when done. Each time that happens ~25% information is lost.

Specialization in 1 or 2 areas is helpful, but have many general skills and domain knowledge. Learn about databases, business analysis, etc.

&lt;h3&gt;What you get from Agile&lt;/h3&gt;
Agile teams are smaller, produce higher quality software that meets the needs of the stakeholders and this basically reduces cost.

Agile gives stakeholders control over budget, schedule and scope. Developers give back quality software that the stakeholders want.

There are documents in agile. But the type and amounts are chosen smartly. Documents are about stable ideas.
There is nothing speculative about agile documentation, which is how traditional methods approach documentation.
If you do TDD your tests will be the specification.

Every iteration the stakeholders can see if the deliverable is where they want to be. With this information they can govern the spending. But the stakeholders have to know what they want and developers have to deliver quality software every iteration.

Repeatable results, not repeatable process.

Addresses the risk early.

&lt;h3&gt;Must Dos&lt;/h3&gt;
Learn at the end of iteration. Refactor every iteration.

Just in time planning. You can only predict the short term.

Continuous Integration.

TTD

Use static debug tools.
Reduce solo development - you must pair!

&lt;h3&gt;Example&lt;/h3&gt;
Eclipse is a very successful agile project. It has delivered its major release on time every year.
Google "Eclipse Way Process" to see the Eclipse agile practice.

Eclipse does a 6 week iteration due to very distributed workforce.

Iteration Stats.
2 wks iteration 32%
4 wks iteraton  21%

No need to be longer then 4 weeks unless.

&lt;h3&gt;Not everything is green field&lt;/h3&gt;
Agile needs to cope with entrenched process, legacy code, and governance of IT.
Traceability is needed sometime, up front modelling needed sometimes, depending on the project type.

&lt;h3&gt;Company&lt;/h3&gt;
Find out how to motivate developers. don't heard cats.
Don't enforce standards, find out what standards people want to follow.

Each team should own their code.

Have a small number of project metrics, too many is bad. Defect trends and burn rate are good. These show a team is delivering value or not and the stakeholders are getting value for money or not.

Help teams that need it. Get ideas from teams that are doing well.

Spend money wisely. Ask....how well has it worked in the past.  Staged finance is another option, try it compared to annual budgets.

HR should reward quality of delivered software, not just years of service.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-4304091718112580535?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/4304091718112580535/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2007/09/scott-ambler-agile-in-real-world.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/4304091718112580535'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/4304091718112580535'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2007/09/scott-ambler-agile-in-real-world.html' title='Scott Ambler - Agile In The Real World'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-2872555970836553364</id><published>2007-06-20T23:04:00.000+01:00</published><updated>2008-08-10T00:34:29.409+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dev Tools'/><title type='text'>Eclipse and SVN</title><content type='html'>There are two Subversion plugins for Eclipse, &lt;a href="http://subclipse.tigris.org/" target="_blank"&gt;Subclipse&lt;/a&gt; and &lt;a href="http://www.polarion.org/index.php?page=overview&amp;amp;project=subversive" target="_blank"&gt;Subversive&lt;/a&gt;. I much prefer the latter, &lt;span class="tahoma8gray"&gt;Subversive in my experience is closer to the CVS plugin for Eclipse which rocks.  &lt;/span&gt;Subversive&lt;span class="tahoma8gray"&gt; plays well with maven2 multi-projects and allows you to have the parent as a general project side by side to the child Java projects in your workspace. That alone gives it a major head start over Subclipse which fails badly when you try to have the two projects together in the workspace.  &lt;/span&gt;

However, Subversive has had a few issues of late and it has had me screaming blue murder at any software developer. But with calm collection I've found the magic combination of things you need in order to have this plugin work.

Update your Mac's SVN installation to the latest version 1.4.4. You can get a binary install from here: &lt;a href="http://downloads.open.collab.net/binaries.html" target="_blank"&gt;http://downloads.open.collab.net/binaries.html&lt;/a&gt;

Update the Subversive plugin in your Eclipse to the latest version. Eclipse Update Site: http://www.polarion.org/projects/subversive/download/1.1/update-site/

Configure your Eclipse Subversive plugin to use Native JavaHL client.

You should be good to go. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-2872555970836553364?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/2872555970836553364/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2007/06/there-are-two-subversion-plugins-for.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/2872555970836553364'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/2872555970836553364'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2007/06/there-are-two-subversion-plugins-for.html' title='Eclipse and SVN'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-8731968922618456942</id><published>2007-06-11T22:49:00.000+01:00</published><updated>2008-08-10T00:26:36.530+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Spring JNDI datasoure binding for testing</title><content type='html'>Use the SimpleNamingContextBuilder in Spring. It's really simple and very handy.

SimpleNamingContextBuilder builder = new SimpleNamingContextBuilder();
DataSource ds = new DriverManagerDataSource("com.db.Driver","jdbc:db2://db.url.com:1234/","username", "password");
builder.bind("java:myDB", ds);
builder.activate();


Now when you use the jee:jndi-lookup in your Spring configuration. e.g.

&amp;lt;jee:jndi-lookup id="dataSource" jndi-name="java:myDB" /&amp;gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-8731968922618456942?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/8731968922618456942/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2007/06/spring-jndi-datasoure-binding-for.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/8731968922618456942'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/8731968922618456942'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2007/06/spring-jndi-datasoure-binding-for.html' title='Spring JNDI datasoure binding for testing'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-7322261992693440160</id><published>2007-05-30T22:44:00.000+01:00</published><updated>2008-08-10T00:36:18.124+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Google'/><category scheme='http://www.blogger.com/atom/ns#' term='Spring'/><title type='text'>Do you know the other Bob?</title><content type='html'>&lt;a href="http://crazybob.org/" target="_blank"&gt;Crazy Bob&lt;/a&gt;, that is, not &lt;a href="http://weblogs.java.net/blog/rmartin/" target="_blank"&gt;Uncle Bob&lt;/a&gt;.

While doing a little reading on Spring I found this old blog post by Crazy Bob : &lt;a href="http://crazybob.org/2006/01/i-dont-get-spring.html" target="_blank"&gt;I don't get Spring&lt;/a&gt;.

You don't get Spring? What? And who the hell is Crazy Bob?

What's not to get about Spring I thought. But after reading the post, he brings up some interesting points which I'm still marinating on.  It's a long post, but a good read.

Crazy Bob, BTW, is the creator of &lt;a href="http://code.google.com/p/google-guice/" target="_blank"&gt;Guice&lt;/a&gt;.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-7322261992693440160?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/7322261992693440160/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2007/05/do-you-know-other-bob.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/7322261992693440160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/7322261992693440160'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2007/05/do-you-know-other-bob.html' title='Do you know the other Bob?'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-9188940448717783160</id><published>2007-05-01T22:37:00.000+01:00</published><updated>2008-08-10T00:29:28.862+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='Craftsmanship'/><title type='text'>Squeeze every last ounce</title><content type='html'>If you are looking to optimize your code for speed during production, and I'm assuming you don't log at debug in production, make sure you wrap your debug log outputs with the &lt;a href="http://logging.apache.org/log4j/docs/api/org/apache/log4j/Category.html#isDebugEnabled()" target="_blank"&gt;isDebugEnabled()&lt;/a&gt; check.

&lt;code&gt;
if (log.isDebugEnabled()) {
log.debug("Count :" + counter);
}
&lt;/code&gt;

The performance gain is considerable when not logging at debug. eg. production.
A debug call without check = ~440 nano sec.
A debug call with isDebugEnabled: ~20 nano sec.

The reason is that it is much quicker to check a boolean than create the log string.  Without the check, the log string is created anyway and then discarded by the logger when it checks if debug is enabled. The flip side to this is that you incur a 20 nano second overhead when you are logging at debug....but that is a price worth paying for production speed.

Before any smart comments come in about concatenating strings....I agree you should use &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/StringBuilder.html" target="_blank"&gt;StringBuilder&lt;/a&gt; to create the strings for logs if they contain variables. :)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-9188940448717783160?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/9188940448717783160/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2007/05/squeeze-every-last-ounce.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/9188940448717783160'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/9188940448717783160'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2007/05/squeeze-every-last-ounce.html' title='Squeeze every last ounce'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-9162694405528210524</id><published>2007-04-27T22:34:00.000+01:00</published><updated>2008-08-10T00:25:51.907+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dev Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Maven'/><title type='text'>Maven eclipse and double classpath entry</title><content type='html'>When creating dependencies in your project's POM the type element is not required for a dependency element.

It is important to include the type element if the dependency is of type ejb.

&amp;lt;dependency&amp;gt;
&amp;lt;groupId&amp;gt;bodog.platform&amp;lt;/groupId&amp;gt;
&amp;lt;artifactId&amp;gt;mailer-ejb&amp;lt;/artifactId&amp;gt;
&amp;lt;version&amp;gt;${platform.version}&amp;lt;/version&amp;gt;
&amp;lt;scope&amp;gt;provided&amp;lt;/scope&amp;gt;
&lt;strong&gt;&amp;lt;type&amp;gt;ejb&amp;lt;/type&amp;gt;&lt;/strong&gt;
&amp;lt;/dependency&amp;gt;

Executing mvn eclipse:eclipse without this type element can lead to double entries in your eclipse .classpath file.

This happens with inconsistent definitions of the dependency, as the eclipse:eclipse plugin creates entries for both ejb and jar types.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-9162694405528210524?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/9162694405528210524/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2007/04/maven-eclipse-and-double-classpath.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/9162694405528210524'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/9162694405528210524'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2007/04/maven-eclipse-and-double-classpath.html' title='Maven eclipse and double classpath entry'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-8237541799255453569</id><published>2007-03-01T22:19:00.000Z</published><updated>2008-08-10T00:27:25.667+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><title type='text'>Script tag. Which is correct?</title><content type='html'>Which is correct?

&amp;lt;script type=&lt;span class="code-quote"&gt;"text/javascript"&lt;/span&gt; src=&lt;span class="code-quote"&gt;"/account-info.js"&lt;/span&gt;/&amp;gt;

&amp;lt;script type=&lt;span class="code-quote"&gt;"text/javascript"&lt;/span&gt; src=&lt;span class="code-quote"&gt;"/account-info.js"&lt;/span&gt; &amp;gt; &amp;lt;/script&amp;gt;
Although both legal xml, the first tag will not work correctly.

If you use the script tag with src attribute you need to have the full open and close tags.

If I was to hazard a guess as to why .... The src content is injected between the open and close tags, which cannot happen if you chose to close within the open tag.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-8237541799255453569?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/8237541799255453569/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2007/03/script-tag-which-is-correct.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/8237541799255453569'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/8237541799255453569'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2007/03/script-tag-which-is-correct.html' title='Script tag. Which is correct?'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-867796413671614780</id><published>2007-02-22T22:15:00.000Z</published><updated>2008-08-09T22:17:05.165+01:00</updated><title type='text'>Couch Potatoes Mourn</title><content type='html'>Next time you sit down and grab that remote, spare a moment for Robert Adler.

Robert Adler was a physicist and prolific inventor, he died on February 15 at the age of 93.

He is best known as the co-inventor of the television remote control.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-867796413671614780?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/867796413671614780/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2007/02/couch-potatoes-mourn.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/867796413671614780'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/867796413671614780'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2007/02/couch-potatoes-mourn.html' title='Couch Potatoes Mourn'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-1649150308934898417.post-1733253108367435732</id><published>2007-02-09T22:02:00.000Z</published><updated>2008-08-10T00:25:51.907+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Dev Tools'/><category scheme='http://www.blogger.com/atom/ns#' term='Maven'/><title type='text'>Do we need another simple text format</title><content type='html'>Maven projects have a nice plug-in called site. This plug-in is used to generate the documentation site for your project. That’s great!

What isn’t great is APT: Almost Plain Text.

APT, as its name suggests, is a very simple text file which, with some simple formatting tricks, can create the HTML output for your site. This is a good idea if you only want to have headings and bullet points. If you want anything else, I’d stay clear of this option. Table and hyperlink are far from simple, and heaven forbid you want sub items.

I suggest using &lt;a href="http://maven.apache.org/maven-1.x/plugins/xdoc/"&gt;xdoc.&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1649150308934898417-1733253108367435732?l=domfarr.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://domfarr.blogspot.com/feeds/1733253108367435732/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://domfarr.blogspot.com/2007/02/do-we-need-another-simple-text-format.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/1733253108367435732'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/1649150308934898417/posts/default/1733253108367435732'/><link rel='alternate' type='text/html' href='http://domfarr.blogspot.com/2007/02/do-we-need-another-simple-text-format.html' title='Do we need another simple text format'/><author><name>Dom Farr</name><uri>http://www.blogger.com/profile/05827713555306511522</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='24' src='http://2.bp.blogspot.com/-jAatCxG7S2A/TojXb2iIyrI/AAAAAAAAAPM/6q79emAp_qA/s220/P1020093.jpg'/></author><thr:total>1</thr:total></entry></feed>
