<?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-23939980</id><updated>2012-01-18T19:56:13.931+11:00</updated><category term='logging'/><category term='installation'/><category term='tools'/><category term='funny'/><category term='news'/><category term='black'/><category term='web'/><category term='tagline'/><category term='api'/><category term='iteration'/><category term='array'/><category term='bike'/><category term='grails'/><category term='accessibility'/><category term='css'/><category term='code coverage'/><category term='spring'/><category term='findbugs'/><category term='expectation'/><category term='virtual'/><category term='launch'/><category term='eclipse'/><category term='mashup'/><category term='hothouse xmas party photo'/><category term='hcard'/><category term='limit'/><category term='xp'/><category term='business'/><category term='sydney'/><category term='java'/><category term='refactoring'/><category term='game'/><category term='exitreality'/><category term='user'/><category term='australia'/><category term='fedex'/><category term='inversion of control'/><category term='microformats'/><category term='pair programming'/><category term='movie'/><category term='timezone'/><category term='build'/><category term='groovy'/><category term='flickr'/><category term='reference'/><category term='html'/><category term='color'/><category term='unit testing'/><category term='design'/><category term='network'/><category term='project'/><category term='automation'/><category term='error'/><category term='ide'/><category term='vista'/><category term='google'/><category term='ioc'/><category term='sky'/><category term='sokoban'/><category term='mail'/><category term='javascript'/><category term='list'/><category term='apple'/><category term='quote'/><category term='jira'/><category term='belt'/><category term='social'/><category term='gadget'/><category term='conference'/><category term='risk'/><category term='gdd'/><category term='validator'/><category term='logo'/><category term='evolution'/><category term='atlassian'/><category term='string'/><category term='plugin'/><category term='planning'/><category term='best practice'/><category term='puzzler'/><category term='sun microsystems'/><category term='trailer'/><category term='wd06'/><category term='windows'/><category term='uml'/><category term='404'/><category term='default'/><category term='youbiquity'/><category term='element'/><category term='cycle'/><category term='ajax'/><category term='howto'/><category term='di'/><category term='startup'/><category term='deployment'/><category term='mapping'/><category term='website'/><category term='gdd08'/><category term='font'/><category term='book'/><category term='blog'/><category term='hijax'/><category term='ie'/><category term='dependecy injection'/><category term='time'/><category term='log4j'/><category term='jquery'/><category term='decompiler'/><category term='search'/><category term='microsoft'/><category term='gdd07'/><category term='server'/><category term='collections'/><category term='maps'/><category term='bar sorrento'/><category term='boolean'/><category term='gmail'/><title type='text'>Java and other things</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default?start-index=101&amp;max-results=100'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>126</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-23939980.post-8540374440275354671</id><published>2011-04-07T01:39:00.002+10:00</published><updated>2011-04-07T01:42:44.921+10:00</updated><title type='text'>Surprise</title><content type='html'>&lt;p&gt;I was washing the dishes after dinner tonight. I was going to put the cuttlery away when I got surprised.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/hanuska/5595010211/"&gt;&lt;img src="http://farm6.static.flickr.com/5308/5595010211_f17d384b8b_m.jpg" alt="Surprise!"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I love you son!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-8540374440275354671?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/8540374440275354671/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=8540374440275354671' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/8540374440275354671'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/8540374440275354671'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2011/04/surprise.html' title='Surprise'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm6.static.flickr.com/5308/5595010211_f17d384b8b_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-6114999633816669933</id><published>2011-04-07T00:59:00.002+10:00</published><updated>2011-04-07T01:03:13.001+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='limit'/><category scheme='http://www.blogger.com/atom/ns#' term='sokoban'/><category scheme='http://www.blogger.com/atom/ns#' term='sky'/><category scheme='http://www.blogger.com/atom/ns#' term='game'/><title type='text'>Sokoban</title><content type='html'>&lt;p&gt;My wife and I were having dinner tonight. As it usually happens out little son finished quickly and was getting restless. So we put him down from his chair and carried on with our meals. Soon after he pulled his chair from the table and pushed it to the door that leads to our backyard. I kept an eye on him, just like any parents would do with a boy who is always up to something. So he pulled this chair to the door, climbed on top of it and the victoriously stood on it, giving me the biggest smile he could. His eye were saying &lt;cite&gt;"Look dad! I did it!"&lt;/cite&gt;&lt;/p&gt;&lt;p&gt;Then I realized what he was up to. He put his little hand up and tried to reach for the air-conditioning unit above him. Near the ceiling. I was impressed with the little guy’s thinking. He used the same logic we (big guys) would use to reach to places that we naturally cannot reach as our bodies do not extend that far. He just underestimated the distance. He is only two. Almost. I praised him for his effort and I told him that he’s done well and he will get there but it may take a few years until he is big enough.&lt;/p&gt;&lt;p&gt;At that very moment I realized that for these little ones with no limits, no boundaries pre-set in their minds the sky is the true limit.&lt;/p&gt;&lt;p&gt;After I asked him to come down (just to be safe) he started pushing that chair around. He maneuvered with it around the kitchen and eventually made it to the very spot he took this chair from. &lt;a href="http://en.wikipedia.org/wiki/Sokoban"&gt;Sokoban&lt;/a&gt;! The only movement my son decided to use was to push the chair. It was fun for him, as well as for me watching him. When he made it do the destination, it dawned on me. He just performed a real-life version of Sokoban. Wow! The kiddo is smart and I wish I was back in 80-ties to re-invent the popular computer game :-)&lt;/p&gt;&lt;p&gt;Don’t limit your kids. Let them explore, invent and make up their own rules for this world they live in.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-6114999633816669933?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/6114999633816669933/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=6114999633816669933' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6114999633816669933'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6114999633816669933'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2011/04/sokoban.html' title='Sokoban'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-2144218874910175310</id><published>2010-09-07T13:00:00.004+10:00</published><updated>2010-09-07T14:05:50.650+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='error'/><category scheme='http://www.blogger.com/atom/ns#' term='404'/><title type='text'>404! Why? Where from?</title><content type='html'>&lt;p&gt;Alright, so you got 404'd! Things aren't that bad because you &lt;a href="http://hanuska.blogspot.com/2010/09/handling-http-404-page-not-found.html"&gt;handled it nicely&lt;/a&gt;, but the real question you have on the tip of your tongue is &lt;cite&gt;"What URL caused this 404?"&lt;/cite&gt;&lt;/p&gt;&lt;p&gt;The request could receive the following attributes that can indicate what caused the error&lt;p&gt;&lt;h2&gt;Where did it come from?&lt;/h2&gt;&lt;p&gt;To get the original URL of the request that is in trouble, look at &lt;strong&gt;javax.servlet.error.request_uri&lt;/strong&gt; request attribute.&lt;/p&gt;&lt;code&gt;&lt;pre style="color:blue"&gt;String uri = (String) request.getAttribute("javax.servlet.error.request_uri");&lt;/pre&gt;&lt;/code&gt;&lt;h2&gt;What caused it?&lt;/h2&gt;&lt;p&gt;To cause of the error can be a HTTP error or an exception that was not handled by the web application and propagated all the way up. The three attributes that will give you more insight are:&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;strong&gt;javax.servlet.error.status_code:&lt;/strong&gt;&lt;br/&gt;An Integer telling the error status code, if any&lt;/li&gt;&lt;li&gt;&lt;strong&gt;javax.servlet.error.exception_type:&lt;/strong&gt;&lt;br/&gt;A Class instance indicating the type of exception that caused the error, if any&lt;/li&gt;&lt;li&gt;&lt;strong&gt;javax.servlet.error.message:&lt;/strong&gt;&lt;br/&gt;A String telling the exception message, passed to the exception constructor&lt;/li&gt;&lt;li&gt;&lt;strong&gt;javax.servlet.error.exception&lt;/strong&gt;:&lt;br/&gt;A Throwable object that is the actual exception thrown&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-2144218874910175310?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/2144218874910175310/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=2144218874910175310' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/2144218874910175310'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/2144218874910175310'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2010/09/404-why-where-from.html' title='404! Why? Where from?'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-879659909659137506</id><published>2010-09-07T10:31:00.004+10:00</published><updated>2010-09-07T14:05:38.238+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='error'/><category scheme='http://www.blogger.com/atom/ns#' term='404'/><title type='text'>Handling HTTP 404 - Page Not Found</title><content type='html'>&lt;p&gt;If you develop web applications, you are most likely familiar with Java Servlets and Java Server Pages (JSP). JSPs can be accessed by a path that directly relates to their relative location to the web app's content root directory. Servlets however are typically accessed via path that match URL patterns defined for each servlet in the servlet mapping element of the deployment descriptor (web.xml).&lt;/p&gt;&lt;p&gt;What happens if a user types in a URL that will reach your web application, but does not map to to any of your servlets nor JSPs? Most likely this occurrence will be handler by the servlet container itself by sending HTTP 404 code back to the user's browser. A &lt;a href="http://en.wikipedia.org/wiki/HTTP_404"&gt;404 page&lt;/a&gt; will be displayed. 404 is a &lt;a href="http://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error"&gt;HTTP response status code&lt;/a&gt; that indicates that &lt;cite&gt;a resource could not be found but may be available again in the future.&lt;/cite&gt; Most of the servlet containers do not serve user-friendly 404 pages.&lt;/p&gt;&lt;p&gt;You are better off handling 404 by the web application itself. The content of the 404 page can be then customized to suit your web application's needs. You could take a &lt;a href="http://www.hongkiat.com/blog/60-really-cool-and-creative-error-404-pages/"&gt;funny approach&lt;/a&gt; or present something more helpful, e.g. a sitemap.&lt;/p&gt;&lt;p&gt;Example from &lt;a href="http://www.youanditee.com"&gt;YOU &amp;amp; I tee&lt;/a&gt; - &lt;a href="http://www.youanditee.com"&gt;couple t-shirts&lt;/a&gt;:&lt;br/&gt;&lt;a href="http://www.flickr.com/photos/youanditee/4966498748/"&gt;&lt;img src="http://farm5.static.flickr.com/4125/4966498748_740b90461a_m_d.jpg" alt="404 Page Not Found"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;So how do we do this?&lt;/p&gt;&lt;h2&gt;Step 1 - Create error page description&lt;/h2&gt;&lt;p&gt;Add an error-page element to your web applications deployment descriptor. Open web.xml file and add a section like the following:&lt;/p&gt;&lt;code&gt;&lt;pre style="color:blue"&gt;&amp;lt;error-page&gt;&lt;br /&gt; &amp;lt;error-code&gt;404&amp;lt;/error-code&gt;&lt;br /&gt; &amp;lt;location&gt;/error404.jsp&amp;lt;/location&gt;&lt;br /&gt;&amp;lt;/error-page&gt;&lt;/pre&gt;&lt;/code&gt;&lt;h2&gt;Step 2 - Create error JSP&lt;/h2&gt;&lt;p&gt;At the location as specified in step 1 create a new JSP file that will serve the content you desire. And that's it really.&lt;/p&gt;&lt;h2&gt;Handling exceptions&lt;/h2&gt;&lt;p&gt;In a similar fashion you can handle uncaught exceptions that would otherwise end up in the user's browser. For example:&lt;p&gt;&lt;code&gt;&lt;pre style="color:blue"&gt;&amp;lt;error-page&gt;&lt;br /&gt; &amp;lt;exception-type&gt;java.lang.RuntimeException&amp;lt;/exception-type&gt;&lt;br /&gt; &amp;lt;location&gt;/exception.jsp&amp;lt;/location&gt;&lt;br /&gt;&amp;lt;/error-page&gt;&lt;/pre&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-879659909659137506?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/879659909659137506/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=879659909659137506' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/879659909659137506'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/879659909659137506'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2010/09/handling-http-404-page-not-found.html' title='Handling HTTP 404 - Page Not Found'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-3382707566933343102</id><published>2010-06-27T02:22:00.003+10:00</published><updated>2010-06-27T02:35:20.329+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='trailer'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='movie'/><title type='text'>JavaZone Trailer: Java 4-ever</title><content type='html'>&lt;p&gt;This is an absolutely awesome movie trailer!&lt;/p&gt;&lt;p&gt;&lt;object width="520" height="317"&gt;&lt;param value="http://www.youtube.com/v/KrfpnbGXL70&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;hd=1" name="movie"&gt;&lt;param value="true" name="allowFullScreen"&gt;&lt;param value="always" name="allowscriptaccess"&gt;&lt;embed width="520" height="317" allowfullscreen="true" allowscriptaccess="always" type="application/x-shockwave-flash" src="http://www.youtube.com/v/KrfpnbGXL70&amp;amp;hl=en_US&amp;amp;fs=1&amp;amp;hd=1"/&gt;&lt;/object&gt;&lt;/p&gt;&lt;p&gt;...from the director of &lt;strong&gt;JAVATAR&lt;/strong&gt; and &lt;strong&gt;.NOT&lt;/strong&gt;&lt;/p&gt;&lt;br /&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-3382707566933343102?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/3382707566933343102/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=3382707566933343102' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/3382707566933343102'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/3382707566933343102'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2010/06/javazone-trailer-java-4-ever.html' title='JavaZone Trailer: Java 4-ever'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-6410804875940079467</id><published>2010-05-03T13:40:00.005+10:00</published><updated>2010-05-03T13:51:24.175+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='inversion of control'/><category scheme='http://www.blogger.com/atom/ns#' term='dependecy injection'/><category scheme='http://www.blogger.com/atom/ns#' term='spring'/><category scheme='http://www.blogger.com/atom/ns#' term='ioc'/><category scheme='http://www.blogger.com/atom/ns#' term='di'/><title type='text'>How to wire a constant in Spring</title><content type='html'>&lt;p&gt;&lt;a href="http://www.springsource.org/"&gt;Spring&lt;/a&gt; is a great framework for dependency injection. It helps creating new instances and inject them with references to other objects via constructor arguments or setter methods.&lt;/p&gt;&lt;p&gt;To create a new instance of a class one simply declares a new bean&lt;/p&gt;&lt;pre style="color:blue"&gt;&amp;lt;bean id="firstDay" class="com.mypackage.Day"&gt;&lt;br /&gt;    &amp;lt;constructor-arg type="java.lang.Integer" value="1" /&gt;&lt;br /&gt;&amp;lt;/bean&gt;&lt;/pre&gt;&lt;p&gt;But what if you do not want to create a new instance. Perhaps you already have a class with instances declared as publicly accessible constants (public static) and you just want to access them in the wiring process.&lt;/p&gt;&lt;p&gt;It's easy to get a hold of a constant. Simply use the following&lt;/p&gt;&lt;pre style="color:blue"&gt;&amp;lt;util:constant id="firstDay" static-field="com.mypackage.Day.MONDAY"/&gt;&lt;/pre&gt;&lt;p&gt;For this to work you'll need to include the following&lt;/p&gt;&lt;pre style="color:blue"&gt;&amp;lt;beans&lt;br /&gt;    xmlns="http://www.springframework.org/schema/beans"&lt;br /&gt;    ...&lt;br /&gt;    xmlns:util="http://www.springframework.org/schema/util"&lt;br /&gt;    xsi:schemaLocation="http://www.springframework.org/schema/util ..."&lt;br /&gt;&gt;&lt;/pre&gt;&lt;p&gt;So there you go, now you have constants wired.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-6410804875940079467?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/6410804875940079467/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=6410804875940079467' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6410804875940079467'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6410804875940079467'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2010/05/how-to-wire-constant-in-spring.html' title='How to wire a constant in Spring'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-1660705247777834696</id><published>2010-01-08T01:13:00.003+11:00</published><updated>2010-01-08T01:22:52.675+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hothouse xmas party photo'/><title type='text'>Xmas Party 2009</title><content type='html'>&lt;p&gt;&lt;a href="http://www.hothouse.com.au/"&gt;HotHouse&lt;/a&gt; had a great &lt;a href="http://blog.hothouse.com.au/2010/01/06/hothouse-christmas-party/"&gt;Christmas party&lt;/a&gt; at &lt;a href="http://www.peatsbite.com.au/"&gt;Peats Bite&lt;/a&gt; restaurant last year.&lt;/p&gt;&lt;p&gt;&lt;img src="http://farm5.static.flickr.com/4033/4212772466_1321356186.jpg" alt="drink"&gt;&lt;/p&gt;&lt;p&gt;See the rest of the photos in my &lt;a href="http://www.flickr.com/photos/hanuska/sets/72157622941393223/"&gt;photo set&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-1660705247777834696?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/1660705247777834696/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=1660705247777834696' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1660705247777834696'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1660705247777834696'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2010/01/xmas-party-2009.html' title='Xmas Party 2009'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm5.static.flickr.com/4033/4212772466_1321356186_t.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-6136941314180104487</id><published>2009-09-03T22:52:00.002+10:00</published><updated>2009-09-03T23:08:44.940+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><title type='text'>jQuery and checkboxes</title><content type='html'>&lt;p&gt;Let's start with a simple checkbox like this:&lt;/p&gt;&lt;pre style="color: blue;"&gt;&amp;lt;input type="checkbox" name="foo" value="bar" /&amp;gt;&lt;/pre&gt;&lt;p&gt;To check whether this checkbox is checked you can do either of the following two alternatives:&lt;/p&gt;&lt;pre style="color: blue;"&gt;$('input[name=foo]').is(':checked')&lt;br /&gt;$('input[name=foo]').attr('checked')&lt;/pre&gt;&lt;p&gt;To check the checkbox we can use the attr() function&lt;/p&gt;&lt;pre style="color: blue;"&gt;$('input[name=foo]').attr('checked', true);&lt;/pre&gt;&lt;p&gt;And likewise to uncheck it&lt;/p&gt;&lt;pre style="color: blue;"&gt;$('input[name=foo]').attr('checked', false);&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-6136941314180104487?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/6136941314180104487/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=6136941314180104487' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6136941314180104487'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6136941314180104487'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2009/09/jquery-and-checkboxes.html' title='jQuery and checkboxes'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-7941438691759788782</id><published>2009-07-31T11:15:00.004+10:00</published><updated>2009-07-31T11:28:00.252+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='server'/><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='startup'/><category scheme='http://www.blogger.com/atom/ns#' term='installation'/><category scheme='http://www.blogger.com/atom/ns#' term='reference'/><category scheme='http://www.blogger.com/atom/ns#' term='website'/><category scheme='http://www.blogger.com/atom/ns#' term='gmail'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='business'/><title type='text'>Leveraging Google to build your business</title><content type='html'>&lt;p&gt;I read a nice post this morning about &lt;a href="http://www.coderoshi.com/2009/07/build-business-with-google.html"&gt;building business with Google&lt;/a&gt; by Eric at &lt;a href="http://www.coderoshi.com/"&gt;過労死 Death by Overcoding&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;It covers many aspects that may be involved in administering your business needs, such as:&lt;ul&gt;&lt;li&gt;Domain registration/host/email/office apps&lt;/li&gt;&lt;li&gt;Phone Management&lt;/li&gt;&lt;li&gt;Blog&lt;/li&gt;&lt;li&gt;The Application&lt;/li&gt;&lt;li&gt;Payments&lt;/li&gt;&lt;li&gt;AdWords&lt;/li&gt;&lt;li&gt;Analytics&lt;/li&gt;&lt;li&gt;Integration/Optimization&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;I recommend reading it to anyone who is starting up a web business. Following the steps mentioned in that blog post can be a real timesaver. And you do not need to hire an admin to do it all.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-7941438691759788782?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/7941438691759788782/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=7941438691759788782' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/7941438691759788782'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/7941438691759788782'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2009/07/leveraging-google-to-build-your.html' title='Leveraging Google to build your business'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-3477159089977715132</id><published>2009-07-30T17:02:00.005+10:00</published><updated>2009-07-30T22:27:41.501+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><category scheme='http://www.blogger.com/atom/ns#' term='best practice'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Detect an AJAX request</title><content type='html'>&lt;p&gt;Many web applications use AJAX nowadays. In a typical scenario, one fills out a form, which is then submitted to the server. If you don't use AJAX or JavaScript is disabled, your form should still submit with no problems. And you receive a new page. If you use unobtrusive enhancement via JavaScript, the form is submitted to the server and the page is updated with the result without a full page reload.&lt;/p&gt;&lt;p&gt;While developing with Grails writing Java and Groovy code, I noticed that a typical pattern is to create two actions in a controller. One to handle normal HTTP POST &lt;em&gt;(e.g. &lt;strong&gt;save&lt;/strong&gt; action)&lt;/em&gt; and one to handle HTTP POST coming from an AJAX request &lt;em&gt;(e.g. &lt;strong&gt;saveAjax&lt;/strong&gt; action)&lt;/em&gt;. The two actions are almost identical. They perform the same business logic. The only difference is what is returned from each action. A &lt;em&gt;normal&lt;/em&gt; action renders a new page. An AJAX one returns whatever your flavor is: XML, JSON, HTML, plain text.&lt;/p&gt;&lt;p&gt;So is there a way to tell the requests (ordinary and AJAX) apart?&lt;/p&gt;&lt;p&gt;You guessed it, there is. AJAX request comes with a special header - &lt;strong&gt;X-Requested-With&lt;/strong&gt;. I usually have my controllers to extend my BaseController, which has a couple of useful methods that I use. &lt;strong&gt;isAjax(request)&lt;/strong&gt; is one of them. And this is what it looks like.&lt;/p&gt;&lt;code&gt;&lt;pre style="color: blue;"&gt;&lt;br /&gt;public static boolean isAjax(request) {&lt;br /&gt;   return "XMLHttpRequest".equals(request.getHeader("X-Requested-With"));&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;p&gt;I hope you'll find it useful. The all you need to do in your action is this:&lt;/p&gt;&lt;code&gt;&lt;pre style="color: blue;"&gt;&lt;br /&gt;def save = {&lt;br /&gt;&lt;br /&gt;    // business logic&lt;br /&gt;    // ...&lt;br /&gt;&lt;br /&gt;    if (isAjax(request)) {&lt;br /&gt;        render([ /* data */ ] as JSON)&lt;br /&gt;    }&lt;br /&gt;    else {&lt;br /&gt;        // render or redirect here&lt;br /&gt;        render(view: 'save', model: [ /* model data */ ])&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-3477159089977715132?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/3477159089977715132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=3477159089977715132' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/3477159089977715132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/3477159089977715132'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2009/07/detect-ajax-request.html' title='Detect an AJAX request'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-5202612675836345797</id><published>2009-07-30T16:35:00.004+10:00</published><updated>2009-07-30T16:48:29.420+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='website'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><title type='text'>Grails.org has a new home page design</title><content type='html'>&lt;p&gt;I absolutely love the new design of the &lt;a href="http://grails.org/"&gt;grails.org&lt;/a&gt; home page. It's sleek, clean, easy to find what you need. Simply brilliant!&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_PDUXIgOmBNo/SnFACzv1ndI/AAAAAAAAAT4/3qu-o3J_o70/s1600-h/grails.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer; width: 200px; height: 107px;" src="http://4.bp.blogspot.com/_PDUXIgOmBNo/SnFACzv1ndI/AAAAAAAAAT4/3qu-o3J_o70/s200/grails.png" alt="" id="BLOGGER_PHOTO_ID_5364139048169741778" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-5202612675836345797?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/5202612675836345797/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=5202612675836345797' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/5202612675836345797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/5202612675836345797'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2009/07/grailsorg-has-new-home-page-design.html' title='Grails.org has a new home page design'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_PDUXIgOmBNo/SnFACzv1ndI/AAAAAAAAAT4/3qu-o3J_o70/s72-c/grails.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-7386853785170953889</id><published>2009-03-13T10:03:00.003+11:00</published><updated>2009-03-13T10:13:41.166+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='reference'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Visual Event</title><content type='html'>&lt;p&gt;This is a really neat tool by &lt;a href="http://www.sprymedia.co.uk/"&gt;Allan Jardine&lt;/a&gt;, a UI developer! It makes it so easy and visual to see what even handlers are attached to the elements of a page. Great addition to my toolbox!&lt;/p&gt;&lt;blockquote&gt;When working with events in Javascript, it is often easy to loose track of what events are subscribed where. This is particularly true if you are using a large number of events, which is typical in a modern interface employing progressive enhancement. Javascript libraries also add another degree of complexity to listeners from a technical point of view, while from a developers point of view they of course can make life much easier! But when things go wrong it can be difficult to trace down why this might be.&lt;/blockquote&gt;&lt;p&gt;Read the whole article about &lt;a href="http://www.sprymedia.co.uk/article/Visual+Event"&gt;Visual Event&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-7386853785170953889?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/7386853785170953889/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=7386853785170953889' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/7386853785170953889'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/7386853785170953889'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2009/03/visual-event.html' title='Visual Event'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-6975460645634161706</id><published>2009-01-18T00:59:00.003+11:00</published><updated>2009-01-18T01:13:00.557+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><title type='text'>jQuery 1.3 upgrade &amp; selector bug</title><content type='html'>&lt;p&gt;I've just upgraded my website to jQuery 1.3. First thing that broke was the attribute selector. This was well documented in the &lt;a href="http://docs.jquery.com/Release:jQuery_1.3"&gt;jQuery 1.3 Release Notes&lt;/a&gt; - &lt;a href="http://docs.jquery.com/Release:jQuery_1.3#Upgrading"&gt;Upgrading&lt;/a&gt; as well as in the &lt;a href="http://docs.jquery.com/Selectors"&gt;documentation&lt;/a&gt;. So this was easily fixed.&lt;/p&gt;&lt;p&gt;Another problem I had was with a selector matching &amp;lt;select&gt; tags, such as&lt;/p&gt;&lt;pre&gt;$('.size select')&lt;/pre&gt;&lt;p&gt;For some reason it is no longer matching the &amp;lt;select&gt; tag, but it's &amp;lt;option&gt; tags instead. There is plenty of buzz about how jQuery switched to &lt;a href="http://sizzlejs.com/"&gt;Sizzle.js&lt;/a&gt; selector engine and all the performance gains. I have not found any information pointing to the change that causes by selector bug. Navigating to the parent node solved the issue for me, but it's more like an ugly hack rather than expected behavior.&lt;/p&gt;&lt;pre&gt;$('.size select').parent()&lt;/pre&gt;&lt;p&gt;Anybody else noticed this problem?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-6975460645634161706?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/6975460645634161706/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=6975460645634161706' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6975460645634161706'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6975460645634161706'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2009/01/jquery-13-upgrade-selector-bug.html' title='jQuery 1.3 upgrade &amp; selector bug'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-7867007071141239480</id><published>2009-01-03T23:24:00.003+11:00</published><updated>2009-01-04T00:13:06.848+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tagline'/><category scheme='http://www.blogger.com/atom/ns#' term='website'/><category scheme='http://www.blogger.com/atom/ns#' term='logo'/><title type='text'>Tagline</title><content type='html'>&lt;p&gt;It has been quite a few busy weeks since my last post. I was heavily snowed down with work on my website. Then there was Christmas and new years celebrations.&lt;/p&gt;&lt;p&gt;Happy new year, everybody! On the optimistic note: &lt;blockquote&gt;Let the new year be better than it is going to be!&lt;/blockquote&gt; :-)&lt;/p&gt;&lt;p&gt;What am I doing right now?&lt;/p&gt;&lt;p&gt;I am thinking about a tag line for my new website. The site will be selling special t-shirts for couples. These t-shirts will have funny designs split 50:50. So the big question is what should the tag line say?&lt;/p&gt;&lt;p&gt;Couple of my &lt;i&gt;(pretty bad)&lt;/i&gt; ideas:&lt;ul&gt;&lt;li&gt;&lt;a href="http://www.coupletshirts.com"&gt;Couple T-Shirts&lt;/a&gt; ...because one is not complete&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.coupletshirts.com"&gt;Couple T-Shirts&lt;/a&gt; two is better than one&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.coupletshirts.com"&gt;Couple T-Shirts&lt;/a&gt; one for you, one for your +1&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;I would like to hear your suggestions.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-7867007071141239480?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/7867007071141239480/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=7867007071141239480' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/7867007071141239480'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/7867007071141239480'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2009/01/tagline.html' title='Tagline'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-4328048999962298627</id><published>2008-12-05T16:06:00.003+11:00</published><updated>2008-12-05T16:27:09.107+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='flickr'/><category scheme='http://www.blogger.com/atom/ns#' term='color'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Colors for the web</title><content type='html'>Do you need to find interesting photos that would enhance your website and would perfectly match its color scheme? I found a perfect tool for that job.&lt;/p&gt;&lt;h3&gt;&lt;a href="http://labs.ideeinc.com/multicolr/?1"&gt;Multicolr Search Lab&lt;/a&gt; by Id&amp;eacute;e Inc.&lt;/h3&gt;&lt;p&gt;And these are the images that match colors of my blog:&lt;br/&gt;&lt;ol style="margin:0;padding:0;list-style-type:none;"&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://labs.ideeinc.com/multicolr/?1#colors=ea9225;"&gt;orange&lt;/a&gt;&lt;br/&gt;&lt;a href="http://www.flickr.com/photos/hanuska/3084166466/"&gt;&lt;img src="http://farm4.static.flickr.com/3153/3084166466_1941678a41_m.jpg" alt="orange color" style="border:1px solid #000; padding:2px;margin:10px 0;"/&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://labs.ideeinc.com/multicolr/?1#colors=ea9225,1c3d78;"&gt;orange &amp; blue&lt;/a&gt;&lt;br/&gt;&lt;a href="http://www.flickr.com/photos/hanuska/3084166474/"&gt;&lt;img src="http://farm4.static.flickr.com/3243/3084166474_e17f3059b6_m.jpg" alt="orange and blue colors" style="border:1px solid #000; padding:2px;margin:10px 0;"/&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://labs.ideeinc.com/multicolr/?1#colors=1c3d78;"&gt;blue&lt;/a&gt;&lt;br/&gt;&lt;a href="http://www.flickr.com/photos/hanuska/3084166460/"&gt;&lt;img src="http://farm4.static.flickr.com/3107/3084166460_044dacfec2_m.jpg" alt="blue color" style="border:1px solid #000; padding:2px;margin:10px 0;"/&gt;&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ol&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-4328048999962298627?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/4328048999962298627/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=4328048999962298627' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4328048999962298627'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4328048999962298627'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/12/colors-for-web.html' title='Colors for the web'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3153/3084166466_1941678a41_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-1225823317334954393</id><published>2008-12-05T15:17:00.005+11:00</published><updated>2008-12-05T16:26:49.823+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='iteration'/><category scheme='http://www.blogger.com/atom/ns#' term='list'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Easy Groovy Iteration</title><content type='html'>&lt;h2&gt;The problem&lt;/h2&gt;&lt;p&gt;Let's say we want to check the correct mimetype and file extension of the file being uploaded. In a typical Java way I would write something like this:&lt;/p&gt;&lt;p&gt;&lt;pre style="color:blue;"&gt;boolean isRightType = "image/jpeg".equals(contentType)&lt;br /&gt;    || "image/png".equals(contentType)&lt;br /&gt;    || "image/x-png".equals(contentType);&lt;br /&gt;&lt;br /&gt;boolean isRightFileExt = filename.endsWith(".png")&lt;br /&gt;    || filename.endsWith(".jpg")&lt;br /&gt;    || filename.endsWith(".jpeg");&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;h2&gt;Groovy solution&lt;/h2&gt;&lt;p&gt;The Groovy way is much simpler and more elegant.&lt;/p&gt;&lt;p&gt;&lt;pre style="color:blue;"&gt;private static CONTENT_TYPES = ["image/jpeg", "image/png", "image/x-png"]&lt;br /&gt;private static FILE_EXTENTIONS = [".png", ".jpg", ".jpeg"]&lt;br /&gt;...&lt;br /&gt;boolean isRightType = CONTENT_TYPES.any { it.equals(contentType) }&lt;br /&gt;boolean isRightFileExt = FILE_EXTENTIONS.any { filename.endsWith(it) }&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;p&gt;This was just a small example. What I really find useful are some of the following constructs that make my programming life really pleasant&lt;/p&gt;&lt;h2&gt;Groovy Iteration&lt;/h2&gt;&lt;h3&gt;each&lt;/h3&gt;&lt;p&gt;Simple collection iteration&lt;/p&gt;&lt;p&gt;&lt;pre style="color:blue;"&gt;def fibList = [1, 1, 2, 3, 5, 8, 13]&lt;br /&gt;fibList.each { println it }  // prints all of the numbers in the list&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;h3&gt;any&lt;/h3&gt;&lt;p&gt;If you need to find out if any element of the collection meets the condition.&lt;/p&gt;&lt;p&gt;&lt;pre style="color:blue;"&gt;def fibList = [1, 1, 2, 3, 5, 8, 13]&lt;br /&gt;assert fibList.any { it == 3 }&lt;br /&gt;assert fibList.any { it - 2 &gt; 10 }&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;This is pretty much equivalent to a Java construct&lt;/p&gt;&lt;p&gt;&lt;pre style="color:blue;"&gt;boolean any(List&lt;E&gt; list, Condition cond)&lt;br /&gt;    for (E e : list) {&lt;br /&gt;        if (cond.meets(e)) {&lt;br /&gt;            return true;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    return false;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;h3&gt;every&lt;/h3&gt;&lt;p&gt;If you need to find out if any element of the collection meets the condition.&lt;/p&gt;&lt;p&gt;&lt;pre style="color:blue;"&gt;def fibList = [1, 1, 2, 3, 5, 8, 13]&lt;br /&gt;assert fibList.every { it &gt; 0 }&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;This is pretty much equivalent to a Java construct&lt;/p&gt;&lt;p&gt;&lt;pre style="color:blue;"&gt;boolean every(List&lt;E&gt; list, Condition cond)&lt;br /&gt;    for (E e : list) {&lt;br /&gt;        if (!cond.meets(e)) {&lt;br /&gt;            return false;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    return true;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;h3&gt;collect&lt;/h3&gt;&lt;p&gt;If you need to create a new collection that contains each element of the original collection transformed in some way.&lt;/p&gt;&lt;p&gt;&lt;pre style="color:blue;"&gt;def fibList = [1, 1, 2, 3, 5, 8, 13]&lt;br /&gt;assert fibList.collect { it - 1 } == [0, 0, 1, 2, 4, 7, 12]&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;This is pretty much equivalent to a Java construct&lt;/p&gt;&lt;p&gt;&lt;pre style="color:blue;"&gt;List&lt;E&gt; every(List&lt;E&gt; list, Command command)&lt;br /&gt;    List&lt;E&gt; result = new ArrayList&lt;E&gt;(list.size());&lt;br /&gt;    for (E e : list) {&lt;br /&gt;        result.add(command(e));&lt;br /&gt;    }&lt;br /&gt;    return result;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;h3&gt;findAll&lt;/h3&gt;&lt;p&gt;If you need to create a new collection that contains all elements that meet the condition.&lt;/p&gt;&lt;p&gt;&lt;pre style="color:blue;"&gt;def fibList = [1, 1, 2, 3, 5, 8, 13]&lt;br /&gt;assert fibList.findAll { it &gt; 1 &amp;&amp; it &lt; 5 } == [2, 3]&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;This is pretty much equivalent to a Java construct&lt;/p&gt;&lt;p&gt;&lt;pre style="color:blue;"&gt;List&lt;E&gt; findAll(List&lt;E&gt; list, Condition cond)&lt;br /&gt;    List&lt;E&gt; result = new ArrayList&lt;E&gt;(list.size());&lt;br /&gt;    for (E e : list) {&lt;br /&gt;        if (!cond.meets(e)) {&lt;br /&gt;            result.add(e);&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    return result;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;h3&gt;find&lt;/h3&gt;&lt;p&gt;If you need to find first element that matches the condition.&lt;/p&gt;&lt;p&gt;&lt;pre style="color:blue;"&gt;def fibList = [1, 1, 2, 3, 5, 8, 13]&lt;br /&gt;assert fibList.find { it &gt; 1 } == 2&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;This is pretty much equivalent to a Java construct&lt;/p&gt;&lt;p&gt;&lt;pre style="color:blue;"&gt;E findAll(List&lt;E&gt; list, Condition cond)&lt;br /&gt;    for (E e : list) {&lt;br /&gt;        if (!cond.meets(e)) {&lt;br /&gt;            return e;&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    return null;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/p&gt;&lt;h2&gt;References&lt;/h2&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://naleid.com/blog/2008/12/01/groovy-makes-iteration-easy/"&gt;Groovy Makes Iteration Easy&lt;/a&gt; by Ted Naleid&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-1225823317334954393?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/1225823317334954393/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=1225823317334954393' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1225823317334954393'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1225823317334954393'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/12/easy-groovy-iteration.html' title='Easy Groovy Iteration'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-1018912639941043441</id><published>2008-11-22T00:01:00.003+11:00</published><updated>2008-11-22T00:08:55.824+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='reference'/><category scheme='http://www.blogger.com/atom/ns#' term='best practice'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>CSS Naming Conventions</title><content type='html'>&lt;p&gt;This is a great article about &lt;a href="http://woork.blogspot.com/2008/11/css-coding-semantic-approach-in-naming.html"&gt;CSS coding: semantic approach in naming convention&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I am keeping this link for any time I will start a new project and will need to look back at some good advise for CSS naming conventions.&lt;/p&gt;&lt;p&gt;Surprisingly I was not far off with my currently undergoing project &lt;a href="http://www.barsorrento.com/"&gt;bar sorrento&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;An image is worth a thousand words.&lt;/p&gt;&lt;p&gt;&lt;a href="http://woork.blogspot.com/2008/11/css-coding-semantic-approach-in-naming.html"&gt;&lt;img src="http://lh4.ggpht.com/_TqPdHmAEwTM/SSBz-YOu2RI/AAAAAAAACnA/WKAiu0pvFO8/sem.png"/&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Nevertheless, I recommend you read the full story.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-1018912639941043441?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/1018912639941043441/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=1018912639941043441' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1018912639941043441'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1018912639941043441'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/11/css-naming-conventions.html' title='CSS Naming Conventions'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://lh4.ggpht.com/_TqPdHmAEwTM/SSBz-YOu2RI/AAAAAAAACnA/WKAiu0pvFO8/s72-c/sem.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-1984048154776571557</id><published>2008-11-21T00:15:00.003+11:00</published><updated>2008-11-21T00:31:47.690+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gmail'/><category scheme='http://www.blogger.com/atom/ns#' term='mail'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Gmail Themes</title><content type='html'>&lt;h3&gt;I'm loving new Gmail Themes!&lt;/h3&gt;&lt;p&gt;The &lt;a href="http://blogoscoped.com/archive/2008-05-19-n72.html" title="Will Gmail get themes?"&gt;big question&lt;/a&gt; has been finally answered.&lt;/p&gt;&lt;p&gt;Official &lt;a href="http://gmailblog.blogspot.com/"&gt;Gmail Blog&lt;/a&gt; &lt;a href="http://gmailblog.blogspot.com/2008/11/spice-up-your-inbox-with-colors-and.html" title="spice up your inbox with colors"&gt;announced&lt;/a&gt; addition of themes today. Users of Gmail can choose from around 30 themes. No need for styling Gmail with Firefox plugins like &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/2108"&gt;Stylish&lt;/a&gt; and a &lt;a href="http://www.hicksdesign.co.uk/journal/google-reader-theme"&gt;theme&lt;/a&gt; from John Hicks &lt;i&gt;(although I liked it quite a lot for some time - until I had to change machine and re-install everything, again)&lt;/i&gt;.&lt;/p&gt;&lt;p&gt;&lt;img src="http://2.bp.blogspot.com/_JE4qNpFW6Yk/SSSRNDDTP7I/AAAAAAAAAMU/LWtu9klI-Bo/s1600/skins_grid.png" /&gt;&lt;/p&gt;&lt;p&gt;My favorite: &lt;b&gt;Shiny&lt;/b&gt;! Just like my laptop.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-1984048154776571557?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/1984048154776571557/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=1984048154776571557' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1984048154776571557'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1984048154776571557'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/11/gmail-themes.html' title='Gmail Themes'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_JE4qNpFW6Yk/SSSRNDDTP7I/AAAAAAAAAMU/LWtu9klI-Bo/s72-c/skins_grid.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-7168135892607983674</id><published>2008-11-19T14:29:00.004+11:00</published><updated>2008-11-19T15:51:05.003+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='user'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><title type='text'>Track 404 with Google Analytics</title><content type='html'>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/raster/58795861/"&gt;&lt;img src="http://farm1.static.flickr.com/31/58795861_8325908a6f_m.jpg" style="float: left; padding: 4px; border: 1px solid #000; margin-right: 10px; margin-bottom: 10px;" title="photo by raster"/&gt;&lt;/a&gt;For many of us it is important as well as interesting to see where our customers go, which pages they visit. Tracking the pages is quite simple with &lt;a href="http://www.google.com/analytics/"&gt;Google Analytics&lt;/a&gt;. However the question is: "How do you track the pages that do not exist?"&lt;/p&gt;&lt;p&gt;If you configure your server or web application to &lt;a href="http://hanuska.blogspot.com/2008/11/grails-and-404-page-not-found.html"&gt;handle 404 error&lt;/a&gt; - page not found (I strongly recommend you &lt;a href="http://www.barsorrento.com/404"&gt;do&lt;/a&gt;) you will have a template page that is displayed every time the user navigates to an invalid URL - a page that does not exist.&lt;/p&gt;&lt;p&gt;So, how do we do this? How do we track our customers that somehow got lost and landed in a location that does not exists, at least not as a valid location that would provide them with the information that they expected.&lt;/p&gt;&lt;p&gt;It's quite easy. If you search for more information you may come across Google Analytics blog post &lt;a href="http://analytics.blogspot.com/2006/09/tip-tracking-404-pages.html"&gt;Tracking 404 Pages&lt;/a&gt;, which is now outdated as the new &lt;b&gt;ga&lt;/b&gt; script is recommended instead of old &lt;b&gt;urchin&lt;/b&gt;. The best source for the answer is Google documentation itself. Simply follow &lt;a href="http://www.google.com/support/analytics/bin/answer.py?hl=en&amp;answer=86927"&gt;these instructions&lt;/a&gt;.&lt;/p&gt;&lt;p style="font-family: 'Trebuchet MS',Trebuchet,Verdana,Sans-Serif; font-style:normal; color:blue;"&gt;&amp;lt;script type="text/javascript"&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;var pageTracker = _gat._getTracker("UA-xxxxx-x");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pageTracker._trackPageview("/404.html?page=" + document.location.pathname + document.location.search + "&amp;from=" + document.referrer);&lt;br /&gt;&amp;lt;/script&gt;&lt;/p&gt;&lt;blockquote&gt;This code sends a virtual pageview of "/404.html?page=[pagename.html?queryparameter]&amp;from=[referrer]" to your account, where [pagename.html?queryparameters] is the missing page name and referrer is the page URL from where the user reached the 404 page.&lt;/blockquote&gt;&lt;p&gt;Then simply look for /404.html in your Top Content report.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-7168135892607983674?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/7168135892607983674/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=7168135892607983674' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/7168135892607983674'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/7168135892607983674'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/11/track-404-with-google-analytics.html' title='Track 404 with Google Analytics'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm1.static.flickr.com/31/58795861_8325908a6f_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-1884920862723789623</id><published>2008-11-17T10:47:00.004+11:00</published><updated>2008-11-17T11:09:35.557+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><category scheme='http://www.blogger.com/atom/ns#' term='best practice'/><title type='text'>Grails and 404 Page Not Found</title><content type='html'>&lt;p&gt;Every good website should have a nice 404 page. This is the page that is displayed when your customers or clients navigate to a destination that does not exist, by typing an invalid URL.&lt;/p&gt;&lt;p&gt;Grails does not give you a nice implementation of 404 error (or any other than 500 error). You need to implement it yourself.&lt;/p&gt;&lt;p&gt;If you search the Internet for examples of how to implement 404 Page Not Found error in Grails, most of the results talk about the following scenario:&lt;/p&gt;&lt;pre style="color:blue"&gt;class UrlMappings {&lt;br /&gt;    static mappings = {&lt;br /&gt;        "500"(controller:"errors", action:"serverError")&lt;br /&gt;        "404"(controller:"errors", action:"notFound")&lt;br /&gt;        "403"(controller:"errors", action:"forbidden")&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;The previous piece of declaration resides inside &lt;b&gt;UrlMappings.groovy&lt;/b&gt; and what it means is that if an error occurs, the request is redirected to &lt;b&gt;errors&lt;/b&gt; controller which will execute in case of 404 the &lt;b&gt;notFound&lt;/b&gt; action. This action could be as simple as&lt;/p&gt;&lt;pre style="color:blue"&gt;def notFound = {&lt;br /&gt;    render(view:"/notFound")&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;This is all good, but if it is all you need to do (render a view - &lt;b&gt;notFound.gsp&lt;/b&gt;) you may as well express it declaratively inside &lt;b&gt;UrlMappings.groovy&lt;/b&gt;&lt;/p&gt;&lt;pre style="color:blue"&gt;class UrlMappings {&lt;br /&gt;    static mappings = {&lt;br /&gt;        "500"(view:'/error')&lt;br /&gt;        "404"(view:'/notFound')&lt;br /&gt;        "403"(view:'/forbidden')&lt;br /&gt;    }&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;This way you won't need a controller class at all. All you need are GSP files in the locations declared in the mappings.&lt;/p&gt;&lt;p&gt;References&lt;ul&gt;&lt;li&gt;&lt;a href="http://grails.org/doc/1.0.x/guide/6.%20The%20Web%20Layer.html#6.4.4%20Mapping%20to%20Response%20Codes"&gt;Mapping Response Codes&lt;/a&gt; Grails documentation&lt;/li&gt;&lt;li&gt;&lt;a href="http://jira.codehaus.org/browse/GRAILS-3219?focusedCommentId=141293#action_141293"&gt;404 UrlMapping does not work with Tomcat&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://amorproximi.blogspot.com/2008/07/more-on-grails-declarative-error.html"&gt;More on Grails declarative error handling&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-1884920862723789623?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/1884920862723789623/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=1884920862723789623' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1884920862723789623'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1884920862723789623'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/11/grails-and-404-page-not-found.html' title='Grails and 404 Page Not Found'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-492282300234399680</id><published>2008-11-12T18:25:00.005+11:00</published><updated>2008-11-12T21:50:14.328+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='logging'/><category scheme='http://www.blogger.com/atom/ns#' term='log4j'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><category scheme='http://www.blogger.com/atom/ns#' term='groovy'/><title type='text'>Grails Logging</title><content type='html'>&lt;p&gt;Configuring logging in Grails is not as simple one would think. Grails uses Log4J as its logging framework. Log4J configuration is stored in the &lt;b&gt;log4j.properties&lt;/b&gt; file. In Grails, this file is generated from &lt;b&gt;Config.groovy&lt;/b&gt; source file.&lt;/p&gt;&lt;p&gt;The official &lt;a href="http://grails.org/Logging"&gt;Grails Logging&lt;/a&gt; documentation says that if you want to have a different logging levels for let's say a specific controller, all controllers and the rest of your application, you should define the logging levels as:&lt;p&gt;&lt;pre style="color:blue;"&gt;grails.'app.controller.YourOtherController'="off,stdout"&lt;br /&gt;grails.'app.controller'="info,stdout"&lt;br /&gt;grails.app="error,stdout"&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Yes, those ticks are required, otherwise you get an error message &lt;i&gt;(No such property: context for class: java.lang.String)&lt;/i&gt;. Don't ask me why. What is also important is the order. Children need to go first.&lt;/p&gt;&lt;p&gt;So that is what the official documentation and few blogs say.&lt;/p&gt;&lt;p&gt;Grails allows you to configure your production, development and testing environments differently if required. I configured Log4J the way that common properties are grouped and placed outside the environment dependent ones. But no matter how I tweaked it, I could not make it to work. For some reason the parent's or child's definition overrides the other, or causes an error.&lt;/p&gt;&lt;p&gt;But there is a solution to this problem after all. Instead of &lt;b&gt;dot notation&lt;/b&gt;, use &lt;b&gt;curly braces&lt;/b&gt;. Like in the following example:&lt;/p&gt;&lt;pre style="color:blue;"&gt;environments {&lt;br /&gt;    development {&lt;br /&gt;        ...&lt;br /&gt;        log4j {&lt;br /&gt;            appender.stdout = ...&lt;br /&gt;            rootLogger="error,logfile,stdout"&lt;br /&gt;            logger {&lt;br /&gt;                grails {&lt;br /&gt;                    app {&lt;br /&gt;                        controller="debug"&lt;br /&gt;                    }&lt;br /&gt;                }&lt;br /&gt;            }&lt;br /&gt;        }&lt;br /&gt;    }&lt;br /&gt;    production {&lt;br /&gt;        ...&lt;br /&gt;    }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;// log4j configuration&lt;br /&gt;log4j {&lt;br /&gt;    appender.logfile=...&lt;br /&gt;    appender.stacktraceLog=...&lt;br /&gt;    rootLogger="debug,logfile"&lt;br /&gt;    logger {&lt;br /&gt;        grails="error"&lt;br /&gt;        StackTrace="error,stacktraceLog"&lt;br /&gt;        ...&lt;br /&gt;    }&lt;br /&gt;    additivity.StackTrace=false&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;This works. Tested with Grails 1.0.3.&lt;/p&gt;&lt;p&gt;Related articles:&lt;ul&gt;&lt;li&gt;&lt;a href="http://grails.org/Logging"&gt;Grails logging&lt;/a&gt; - official documentation,&lt;/li&gt;&lt;li&gt;&lt;a href="http://groups.google.com/group/groovymn/browse_thread/thread/ba085c36ca21591f?pli=1"&gt;Logging configuration&lt;/a&gt; - Groovy Users of Minnesota,&lt;/li&gt;&lt;li&gt;&lt;a href="http://blog.sinequanon.net/2008/09/grails-logging/"&gt;Grails logging&lt;/a&gt; - sine qua non&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-492282300234399680?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/492282300234399680/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=492282300234399680' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/492282300234399680'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/492282300234399680'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/11/grails-logging.html' title='Grails Logging'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-6647723221338130643</id><published>2008-11-11T09:45:00.007+11:00</published><updated>2008-11-11T11:59:21.013+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='font'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='bar sorrento'/><title type='text'>What The Font ?!</title><content type='html'>&lt;p&gt;I am creating a website for my wife's coffee shop and I needed to find out the font type they used on the signs and the menus. I was really wondering how I could identify the font.&lt;/p&gt;&lt;p&gt;It turned out to be quite simple. Thanks to &lt;a href="http://www.myfonts.com/WhatTheFont/"&gt;WhatTheFont?!&lt;/a&gt;&lt;/p&gt;&lt;p&gt;The process was following:&lt;/p&gt;&lt;ol&gt;&lt;li&gt;This morning I snapped a photo of the sign,&lt;br /&gt;&lt;a href="http://www.flickr.com/photos/hanuska/3020538324/"&gt;&lt;img style="border: 1px solid rgb(0, 0, 0); padding: 4px; margin-top: 6px;" src="http://farm4.static.flickr.com/3141/3020538324_e5f29f39d9_m.jpg" /&gt;&lt;/a&gt;&lt;/li&gt;&lt;li&gt;Slightly modified it in &lt;a href="http://www.gimp.org/"&gt;GIMP&lt;/a&gt;,&lt;br /&gt;&lt;img style="border: 1px solid rgb(0, 0, 0); padding: 4px; margin-top: 6px;" src="http://3.bp.blogspot.com/_PDUXIgOmBNo/SRjX4a3bLYI/AAAAAAAAAJ8/uzQiv0Kqx-4/s400/bs_fixed_small.gif" /&gt;&lt;/li&gt;&lt;li&gt;uploaded it to &lt;a href="http://www.myfonts.com/WhatTheFont/"&gt;WhatTheFont?!&lt;/a&gt;,&lt;/li&gt;&lt;li&gt;and voilà, the font is &lt;a href="http://www.linotype.com/43410/isonormregular-font.html"&gt;Isonorm&lt;/a&gt;&lt;br/&gt;&lt;img style="border: 1px solid rgb(0, 0, 0); padding: 4px; margin-top: 6px;" src="http://3.bp.blogspot.com/_PDUXIgOmBNo/SRjX-GCobvI/AAAAAAAAAKE/iwiv9rvWpIY/s400/font_small.png"/&gt;&lt;br /&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Yeah, I know. It is not quite quite the same, the letter "r" looks a bit different, but other than that, it's a perfect match. I am quite happy with it. Much better than going through thousands of fonts manually.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-6647723221338130643?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/6647723221338130643/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=6647723221338130643' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6647723221338130643'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6647723221338130643'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/11/what-font.html' title='What The Font ?!'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3141/3020538324_e5f29f39d9_t.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-500571227914953447</id><published>2008-11-11T09:26:00.006+11:00</published><updated>2008-11-11T15:43:13.308+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='ie'/><category scheme='http://www.blogger.com/atom/ns#' term='vista'/><category scheme='http://www.blogger.com/atom/ns#' term='xp'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><category scheme='http://www.blogger.com/atom/ns#' term='microsoft'/><title type='text'>Testing on IE6, IE7 and IE8</title><content type='html'>&lt;p&gt;Have you ever needed to test your web app in multiple versions if Internet Explorer? It is not quite common to have IE6 and IE7 (or IE8) installed on the same computer side by side.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.tech-recipes.com/rx/1188/ie7_use_ie6_ie7_together/"&gt;It&lt;/a&gt; &lt;a href="http://blogs.msdn.com/ie/archive/2006/11/30/ie6-and-ie7-running-on-a-single-machine.aspx"&gt;is&lt;/a&gt; &lt;a href="http://tredosoft.com/IE7_standalone"&gt;possible&lt;/a&gt;. But if you have already upgraded to IE7, there is no going back. Or is there?&lt;/p&gt;&lt;p&gt;Well, you can still test on both browsers. Microsoft quite conveniently produced a free Virtual PC image for IE6 compatibility testing. Go to &lt;a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=21EABB90-958F-4B64-B5F1-73D0A413C8EF&amp;displaylang=en"&gt;Internet Explorer Application Compatibility VPC Image&lt;/a&gt; page, where you can download images for IE 6, 7 and 8 Beta 2.&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;&lt;b&gt;Internet Explorer 6&lt;/b&gt; on Windows XP SP3&lt;/li&gt;&lt;li&gt;&lt;b&gt;Internet Explorer 7&lt;/b&gt; on Windows XP SP2&lt;/li&gt;&lt;li&gt;&lt;b&gt;Internet Explorer 8 Beta 2&lt;/b&gt; on Windows XP SP3&lt;/li&gt;&lt;li&gt;&lt;b&gt;Internet Explorer 7&lt;/b&gt; on Windows Vista&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;All you need to run these images is &lt;a href="http://www.microsoft.com/windows/products/winfamily/virtualpc/default.mspx"&gt;Microsoft Virtual PC&lt;/a&gt;. It's all free.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-500571227914953447?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/500571227914953447/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=500571227914953447' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/500571227914953447'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/500571227914953447'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/11/testing-on-ie6-ie7-and-ie8.html' title='Testing on IE6, IE7 and IE8'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-4875751985613484293</id><published>2008-11-09T21:11:00.000+11:00</published><updated>2008-11-09T21:13:38.201+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='validator'/><category scheme='http://www.blogger.com/atom/ns#' term='microformats'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='hcard'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='best practice'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><title type='text'>hCard microformat validator</title><content type='html'>&lt;p&gt;I was creating a contact page for a website and I wanted to use &lt;a href="http://microformats.org/wiki/hcard"&gt;hCard&lt;/a&gt; &lt;a href="http://microformats.org/"&gt;microformat&lt;/a&gt; to encode the address, telephone, fax and the geo location. After I created it, I looked for a way to quickly validate it and I found&lt;/p&gt;&lt;h3 style="background: transparent url(http://hcard.geekhood.net/i/logo.png) no-repeat scroll 0 0; padding-left: 45px; line-height: 1.5;"&gt;&lt;a href="http://hcard.geekhood.net/" style="color: black; font-family: 'Solex Medium','Myriad Web','Myriad Pro','Calibri','Arial',sans-serif; font-size: 1.6em;"&gt;hCard micro&lt;span style="color:#666;"&gt;format&lt;/span&gt; Validator &lt;small style="vertical-align: top;"&gt;1.0&lt;/small&gt;&lt;/a&gt;&lt;/h3&gt;&lt;p&gt;What a great service! I must tell you, this service is super easy to use. Just type in a URL of the page that contains hCard data and get the results instantly. I read the spec but... I still made few mistakes that were promptly brought to my attention.&lt;/p&gt;&lt;p&gt;I made a typo and instead of &lt;strong&gt;adr&lt;/strong&gt; I used &lt;strong&gt;addr&lt;/strong&gt;, which rendered couple of nested elements invalid. Ok, that was a quick fix.&lt;/p&gt;&lt;p&gt;The telephone number is shop's &lt;span style="font-style: italic;"&gt;(this website is for a retail store)&lt;/span&gt; and I marked the telephone number as shop, which is invalid. The valid values are: &lt;span style="font-family: courier new;"&gt;home, work, pref, fax, cell, voice, video, pager, car, msg, modem, bbs, isdn, pcs&lt;/span&gt;. Another easy fix! The same went for the fax number.&lt;/p&gt;&lt;p&gt;Lastly, the email address that I entered was of a domain that did not register itself yet. The message I got was:&lt;/p&gt;&lt;blockquote&gt;Lookup of e-mail's domain “notyetregistered.com.au” failedVerify that e-mail address is correct.&lt;/blockquote&gt;&lt;p&gt;Wow, I did not expect such a thorough check!&lt;/p&gt;&lt;p&gt;Another good point for this validator is that it not only tells you what is wrong, but it also links to a FAQ page where the problem is explained.&lt;/p&gt;&lt;p&gt;Well done and thank you! Now this contact page validates 100%!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-4875751985613484293?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/4875751985613484293/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=4875751985613484293' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4875751985613484293'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4875751985613484293'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/11/hcard-microformat-validator.html' title='hCard microformat validator'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-977531213139863919</id><published>2008-11-07T15:32:00.004+11:00</published><updated>2008-11-07T15:43:24.320+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='logging'/><category scheme='http://www.blogger.com/atom/ns#' term='grails'/><title type='text'>Fatal Error in the logs by Grails</title><content type='html'>&lt;p&gt;I recently started working on a project using Grails and the following message in the logs appeared consistently and annoyed me quite a lot.&lt;p&gt;&lt;pre&gt;[Fatal Error] :-1:-1: Premature end of file.&lt;/pre&gt;&lt;p&gt;So I started digging through the code and searching the web for an answer. And I found it. It is a bug that has been reported to Grails and you can find it at &lt;a href="http://jira.codehaus.org/browse/GRAILS-3088"&gt;GRAILS-3088&lt;/a&gt;. It apparently affects Grails 1.0.3 (which I am using) and it should be fixed in next release, 1.0.4.&lt;/p&gt;&lt;p&gt;The bug is triggered with each request from Firefox 3 and Opera 9.5 and even Firefox 2 if you render the response as "text/xml" using&lt;/p&gt;&lt;pre&gt;withFormat { xml { render(contentType:"text/xml"){ ... } } }&lt;/pre&gt;&lt;p&gt;The current &lt;a href="http://jira.codehaus.org/browse/GRAILS-3088?focusedCommentId=138950#action_138950"&gt;workaround suggested&lt;/a&gt; by Graeme Rocher is to edit &lt;strong&gt;Config.groovy&lt;/strong&gt; file and remove (or comment out) "text/xml" from the Grails MIME types mapping&lt;p&gt;&lt;pre&gt;grails.mime.types = [ html: ['text/html','application/xhtml+xml'],&lt;br /&gt;//                      xml: ['text/xml', 'application/xml'],&lt;br /&gt;                      text: 'text-plain',&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;This works for me. No more annoying messages in the logs. I am not quite sure how or if it affects XML responses. But I do not need those for now, so I will worry about that later, if I need to&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-977531213139863919?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/977531213139863919/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=977531213139863919' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/977531213139863919'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/977531213139863919'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/11/fatal-error-in-logs-by-grails.html' title='Fatal Error in the logs by Grails'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-3049881460947973683</id><published>2008-10-11T23:58:00.004+11:00</published><updated>2008-10-12T00:10:24.633+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='javascript'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='jquery'/><category scheme='http://www.blogger.com/atom/ns#' term='best practice'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>HTML id attribute valid values</title><content type='html'>&lt;p&gt;Many (if not all) HTML tags can have &lt;code&gt;id&lt;/code&gt; attribute. This attribute uniquely identifies the tag on a single HTML page. Web designers use ids when they design the page using CSS. Web developers use ids for retrieving DOM objects via JavaScript or functional testing of their sites.&lt;/p&gt;&lt;p&gt;Despite the wide use of &lt;code&gt;id&lt;/code&gt; attribute, many of us get it wrong, the value of the &lt;code&gt;id&lt;/code&gt; tag attribute to be precise.&lt;/p&gt;&lt;p&gt;According to the &lt;a title="HTML 4.0 specification for basic types" href="http://www.w3.org/TR/REC-html40/types.html#type-name" id="m.:2"&gt;HTML 4.0 specification for basic types&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;&lt;strong&gt;ID&lt;/strong&gt; and &lt;strong&gt;NAME&lt;/strong&gt; tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").&lt;/blockquote&gt;&lt;p&gt;This is a very basic rule and yet many of us get it wrong, not on purpose of course.&lt;/p&gt;&lt;p&gt;The most common mistake come with web applications that display data from a database. Most commonly a database record is uniquely identified in the database by a record id. This is number that is unique per database table. The common mistake is to use this &lt;i&gt;(database)&lt;/i&gt; &lt;code&gt;id&lt;/code&gt; as a value of the &lt;code&gt;id&lt;/code&gt; attribute on a HTML page. The problem is that the database id is a number, but HTML ids cannot start with a digit. Remember HTML ids must start with a letter A-Z or a-z. Therefore the database id needs to be pre-pended with at least a single letter.&lt;/p&gt;&lt;p&gt;Even worse, I have seen web applications to use entity names as ids. These names are semi-unique, but may contain international characters, characters outside of A-Z and a-z range and even spaces.&lt;/p&gt;&lt;p&gt;If you are going to use a prefix before the database &lt;code&gt;id&lt;/code&gt; and you want to separate the two, I strongly advise you to use underscore ("_"). My reasons are the following:&lt;/p&gt;&lt;p&gt;&lt;b&gt;Don't use spaces (" ")!&lt;/b&gt; The reason for this is simple. Space character is not a valid for id or name attribute.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Don't use hyphens ("-")!&lt;/b&gt; If you intend to use an &lt;code&gt;id&lt;/code&gt; with JavaScript in the form &lt;code&gt;document.idname.value&lt;/code&gt;, you must use a name that is a valid JavaScript variable name. Hyphen (or minus) would break the JavaScript on your page.&lt;/p&gt;&lt;p&gt;&lt;b&gt;Don't use colons (":") or periods (".")!&lt;/b&gt; These characters are valid, however if you decide to use CSS or some JavaScript library that uses CSS-like selectors (e.g. &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;), periods will be mistaken for CSS class selectors and colons for pseudo-class selectors (e.g. &lt;code&gt;:hover&lt;/code&gt; for links).&lt;/p&gt;&lt;p&gt;For the geeky ones, it is possible to start an id with a number (if you really want to) but you need to represent this number with its Unicode escaped character.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-3049881460947973683?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/3049881460947973683/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=3049881460947973683' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/3049881460947973683'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/3049881460947973683'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/10/html-id-attribute-valid-values.html' title='HTML id attribute valid values'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-2953373363639115</id><published>2008-09-12T13:44:00.006+10:00</published><updated>2008-11-07T15:44:24.862+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='launch'/><category scheme='http://www.blogger.com/atom/ns#' term='virtual'/><category scheme='http://www.blogger.com/atom/ns#' term='exitreality'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>ExitReality launch</title><content type='html'>&lt;a href="http://www.exitreality.com/"&gt;ExitReality&lt;/a&gt;, the company &lt;a href="http://hanuska.blogspot.com/2008/06/exitreality-goes-to-beta.html"&gt;I blogged about&lt;/a&gt; before, is having a public launch event next Thursday 18th September 2008 at Federation Square in Melbourne, Victoria (&lt;a href="http://maps.google.com.au/maps?f=q&amp;amp;hl=en&amp;amp;geocode=&amp;amp;q=Corner+of+St+Kilda+Rd+%26+Flinders+St,+Melbourne,+VIC,+Australia&amp;amp;sll=-37.817785,144.968183&amp;amp;sspn=0.007255,0.016522&amp;amp;ie=UTF8&amp;amp;ll=-37.817353,144.967453&amp;amp;spn=0.001761,0.004131&amp;amp;t=h&amp;amp;z=19"&gt;map&lt;/a&gt;).&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-2953373363639115?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/2953373363639115/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=2953373363639115' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/2953373363639115'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/2953373363639115'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/09/exitreality-launch.html' title='ExitReality launch'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-8401611664806252244</id><published>2008-09-05T00:19:00.003+10:00</published><updated>2008-09-05T00:27:54.094+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ide'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='best practice'/><title type='text'>Process terminated with exit code 3</title><content type='html'>&lt;p&gt;This is a reminder to myself.&lt;/p&gt;&lt;p&gt;I had a trouble with &lt;a href="http://www.jetbrains.com/idea/"&gt;IntelliJ IDEA&lt;/a&gt; today. It was the same as I had some time ago on a different computer.&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight:bold;"&gt;Process terminated with exit code 3&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_PDUXIgOmBNo/SL_vXbWzN-I/AAAAAAAAAIs/8EK0GdU_Q4s/s1600-h/error.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; align: left; cursor: pointer;" src="http://2.bp.blogspot.com/_PDUXIgOmBNo/SL_vXbWzN-I/AAAAAAAAAIs/8EK0GdU_Q4s/s400/error.png" alt="" id="BLOGGER_PHOTO_ID_5242171677041965026" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;After a bit of digging around the &lt;a href="http://www.jetbrains.net/jira/browse/IDEA-17329"&gt;solution&lt;/a&gt; was obvious: &lt;i&gt;increase the maximum heap size in Settings | Compiler&lt;/i&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-8401611664806252244?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/8401611664806252244/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=8401611664806252244' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/8401611664806252244'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/8401611664806252244'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/09/process-terminated-with-exit-code-3.html' title='Process terminated with exit code 3'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_PDUXIgOmBNo/SL_vXbWzN-I/AAAAAAAAAIs/8EK0GdU_Q4s/s72-c/error.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-4346819247410620967</id><published>2008-08-31T13:24:00.003+10:00</published><updated>2008-08-31T13:43:40.688+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='server'/><category scheme='http://www.blogger.com/atom/ns#' term='jira'/><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='timezone'/><category scheme='http://www.blogger.com/atom/ns#' term='default'/><category scheme='http://www.blogger.com/atom/ns#' term='howto'/><category scheme='http://www.blogger.com/atom/ns#' term='reference'/><category scheme='http://www.blogger.com/atom/ns#' term='time'/><category scheme='http://www.blogger.com/atom/ns#' term='best practice'/><title type='text'>How to get the server's timezone</title><content type='html'>&lt;h2&gt;The problem&lt;/h2&gt;&lt;p&gt;How to get the server's timezone display name correctly and display it to the user in his locale.&lt;/p&gt;&lt;h3&gt;server's default timezone&lt;/h3&gt;&lt;p&gt;Firstly, you need to get the server's default timezone. This is easily achieved by the following call&lt;/p&gt;&lt;code style="color:blue;"&gt;final TimeZone timeZone = TimeZone.getDefault();&lt;code&gt;&lt;h3&gt;use daylight time?&lt;/h3&gt;&lt;p&gt;Secondly, you need to find out if this timezone uses daylight time. This is important as some timezones change their names during daylight saving. Don't use the &lt;code&gt;TimeZone.useDaylightTime()&lt;/code&gt; method&lt;/p&gt;&lt;code style="color:blue;"&gt;//final boolean daylight = timeZone.useDaylightTime();&lt;/code&gt;&lt;p&gt;This method works fine only for systems where the timezone never changes. If the administrator changes the time on the server, this change won't be reflected in subsequent calls. What you need to do instead, is to find out is the daylight savings is on &lt;strong&gt;right now&lt;/strong&gt;.&lt;/p&gt;&lt;code style="color:blue;"&gt;final boolean daylight = timeZone.inDaylightTime(new Date());&lt;/code&gt;&lt;h3&gt;user's locale&lt;/h3&gt;&lt;p&gt;The last important step is to get the right locale, the locale you want this timezone name to display in. You could call &lt;code&gt;Locale.getDefault()&lt;/code&gt;, but this returns server's default locale. You want the locale that the user is using. In a web application, the user's locale can be obtained from &lt;a href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/ServletRequest.html#getLocale()"&gt;&lt;code&gt;getLocale()&lt;/code&gt;&lt;/a&gt; method of &lt;code&gt;ServletRequest&lt;/code&gt; object.&lt;/p&gt;&lt;code style="color:blue;"&gt;final Locale locale = servletRequest.getLocale();&lt;/code&gt;&lt;h3&gt;final step - timezone display name&lt;/h3&gt;&lt;p&gt;Now we can call &lt;code&gt;getDisplayName&lt;/code&gt; method with all required parameters.&lt;/p&gt;&lt;code style="color:blue;"&gt;return timeZone.getDisplayName(daylight, TimeZone.LONG, locale);&lt;/code&gt;&lt;h2&gt;Solution&lt;/h2&gt;&lt;p&gt;To put this all together, the final solution may look like this method&lt;/p&gt;&lt;code&gt;&lt;pre style="color:blue;"&gt;private String getServerTimeZoneDisplayName()&lt;br /&gt;{&lt;br /&gt;    final TimeZone timeZone = TimeZone.getDefault();&lt;br /&gt;    final boolean daylight = timeZone.inDaylightTime(new Date());&lt;br /&gt;    final Locale locale = servletRequest.getLocale();&lt;br /&gt;    return timeZone.getDisplayName(daylight, TimeZone.LONG, locale);&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;h2&gt;References&lt;/h2&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;Java &lt;a href="http://java.sun.com/javase/6/docs/api/java/util/TimeZone.html"&gt;TimeZone&lt;/a&gt; class&lt;/li&gt;&lt;li&gt;JEE &lt;a href="http://java.sun.com/j2ee/sdk_1.3/techdocs/api/javax/servlet/ServletRequest.html"&gt;ServletRequest&lt;/a&gt; class&lt;/li&gt;&lt;li&gt;&lt;a href="http://jira.atlassian.com/browse/JRA-15488"&gt;JRA-15488&lt;/a&gt; - Shows incorrect time (zone) when subscribing to filter&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-4346819247410620967?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/4346819247410620967/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=4346819247410620967' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4346819247410620967'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4346819247410620967'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/08/how-to-get-servers-timezone.html' title='How to get the server&apos;s timezone'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-2782141480111097465</id><published>2008-06-20T14:36:00.003+10:00</published><updated>2008-06-20T14:45:44.229+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><category scheme='http://www.blogger.com/atom/ns#' term='tools'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Wordle</title><content type='html'>&lt;p&gt;This is my blog through &lt;a href="http://wordle.net/"&gt;Wordle&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://wordle.net/gallery/02175/hanuska" title="Wordle: hanuska"&gt;&lt;img src="http://wordle.net/thumb/02175/hanuska" style="padding:4px;border:1px solid #ddd"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-2782141480111097465?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/2782141480111097465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=2782141480111097465' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/2782141480111097465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/2782141480111097465'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/06/wordle.html' title='Wordle'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-4593775179059065345</id><published>2008-06-20T00:14:00.006+10:00</published><updated>2008-06-20T00:34:16.344+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sydney'/><category scheme='http://www.blogger.com/atom/ns#' term='atlassian'/><category scheme='http://www.blogger.com/atom/ns#' term='apple'/><title type='text'>Campers in front of Apple store</title><content type='html'>&lt;p&gt;I heard a lot of buzz about new Apple store opening in Sydney. I am not a fan of Apple. Some of my colleagues are. Well most of them since Atlassian started equipping its staff with Mac Pro, MacBook and MacBook Air computers.&lt;/p&gt;&lt;p&gt;So this morning I thought I would go and have a look at the folks camping in front of this store that was due to be opened tonight&lt;/p&gt;&lt;p&gt;And yes, there they were. Sitting on the foldable chairs, covered with doonas and in sleeping bags.&lt;/p&gt;&lt;p&gt;I really felt sorry for them. Trading their (life)time for something they can already buy from a nearby store - there are already stores here that sell Macs.&lt;/p&gt;&lt;p&gt;Losers!&lt;/p&gt;&lt;p&gt;But then it dawned at me. What a great opportunity, once in a lifetime, to spend a night with your friends doing something unusual - to (legally) camp in the middle of the city. Priceless!&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/hanuska/2592163535/"&gt;&lt;img src="http://farm4.static.flickr.com/3275/2592163535_ac2118b9c6_t.jpg" style="float:left; padding: 4px; border: #000 1px solid; margin-right: 10px;"&gt;&lt;/a&gt;&lt;a href="http://www.flickr.com/photos/hanuska/2593006658/"&gt;&lt;img src="http://farm4.static.flickr.com/3171/2593006658_f5677efe48_t.jpg" style="float:left; padding: 4px; border: #000 1px solid; margin-right: 10px;"&gt;&lt;/a&gt;&lt;a href="http://www.flickr.com/photos/hanuska/2592174195/"&gt;&lt;img src="http://farm4.static.flickr.com/3267/2592174195_fc5eaa67f9_t.jpg" style="float:left; padding: 4px; border: #000 1px solid;"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-4593775179059065345?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/4593775179059065345/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=4593775179059065345' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4593775179059065345'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4593775179059065345'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/06/campers-in-front-of-apple-store.html' title='Campers in front of Apple store'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3275/2592163535_ac2118b9c6_t.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-4094668221553128471</id><published>2008-06-19T22:33:00.010+10:00</published><updated>2008-06-20T00:07:35.185+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='social'/><category scheme='http://www.blogger.com/atom/ns#' term='installation'/><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='atlassian'/><category scheme='http://www.blogger.com/atom/ns#' term='australia'/><category scheme='http://www.blogger.com/atom/ns#' term='sydney'/><category scheme='http://www.blogger.com/atom/ns#' term='gdd08'/><category scheme='http://www.blogger.com/atom/ns#' term='flickr'/><category scheme='http://www.blogger.com/atom/ns#' term='gdd'/><category scheme='http://www.blogger.com/atom/ns#' term='virtual'/><category scheme='http://www.blogger.com/atom/ns#' term='exitreality'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Firefox 3</title><content type='html'>&lt;p&gt;I, like many others, downloaded &lt;a href="http://www.mozilla.com/firefox/"&gt;Firefox 3&lt;/a&gt; yesterday. It was an attempt for a Guinness World Record titled &lt;a href="http://www.spreadfirefox.com/en-US/worldrecord/"&gt;Spread Firefox&lt;/a&gt;. The result was more than 8 million downloads in a single day. Quite impressive!&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/hanuska/2592405482/"&gt;&lt;img src="http://farm4.static.flickr.com/3123/2592405482_788e39f394_t.jpg" style="float:left; border: #000 1px solid; padding: 4px; margin: 0 10px 10px 0" /&gt;&lt;/a&gt; I did not have time to install it yesterday as I was on a holiday, busy attending &lt;a href="http://code.google.com/events/developerday/2008/home.html"&gt;Google Developer Day 2008&lt;/a&gt;. See my &lt;a href="http://www.flickr.com/photos/hanuska/" rel="me"&gt;photos on Flickr&lt;/a&gt;. I met there with few fellow developers, like &lt;span class="vcard"&gt;&lt;a href="http://www.linkedin.com/in/dmitrybaranovskiy" rel="met friend colleague" class="fn url"&gt;Dmitry Baranovskiy&lt;/a&gt;&lt;/span&gt;, who you can see speaking at &lt;a href="http://south08.webdirections.org/?page_id=7#post-39"&gt;Web Directions South&lt;/a&gt; soon and Carlos Mari, Director of &lt;a href="http://www.carloslabs.com/"&gt;Carlos Labs&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;So I installed Firefox 3 today. I must say that I am quite impressed with the browser itself and with the ease of upgrading. I expected few hiccups on the way but it was all smooth.&lt;/p&gt;&lt;p&gt;Out of my 31 add-ons installed on Firefox 2 only six do not work. The six that no longer work are:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;AutoCopy&lt;/li&gt;&lt;li&gt;ColorZilla&lt;/li&gt;&lt;li&gt;EROnline (Exit Reality)&lt;/li&gt;&lt;li&gt;Firebug&lt;/li&gt;&lt;li&gt;Google Browser Sync&lt;/li&gt;&lt;li&gt;Link Alert&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;I am going to miss AutoCopy and ColorZilla dearly. I am sure that &lt;a href="http://www.exitreality.com/"&gt;Exit Reality&lt;/a&gt; will release a new plug-in real soon.&lt;/p&gt;&lt;p&gt;And for Google Browser Sync - it's a real shame that this is discontinued. But I knew this in advance, therefore I backed up my bookmarks and returned back to my favorite &lt;a href="http://www.foxmarks.com/"&gt;Foxmarks&lt;/a&gt;&lt;/p&gt;&lt;p&gt;In case you wondered what add-ons I use and currently have installed, here is a list:&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Download Statusbar&lt;/li&gt;&lt;li&gt;Dummy Lipsum&lt;/li&gt;&lt;li&gt;Dictionary English (AU)&lt;/li&gt;&lt;li&gt;Dictionary English (US)&lt;/li&gt;&lt;li&gt;FlashGot&lt;/li&gt;&lt;li&gt;Forecastfox&lt;/li&gt;&lt;li&gt;Google Earth&lt;/li&gt;&lt;li&gt;Google Gears&lt;/li&gt;&lt;li&gt;Google Notebook&lt;/li&gt;&lt;li&gt;Greasemonkey&lt;/li&gt;&lt;li&gt;Html Validator&lt;/li&gt;&lt;li&gt;IE Tab&lt;/li&gt;&lt;li&gt;Live HTTP Headers&lt;/li&gt;&lt;li&gt;MeasureIt&lt;/li&gt;&lt;li&gt;meebo&lt;/li&gt;&lt;li&gt;Mouse Gestures&lt;/li&gt;&lt;li&gt;Operator&lt;/li&gt;&lt;li&gt;PDF Download&lt;/li&gt;&lt;li&gt;Personas for Firefox&lt;/li&gt;&lt;li&gt;Quick Locale Switcher&lt;/li&gt;&lt;li&gt;Redirect Remover&lt;/li&gt;&lt;li&gt;Total Validator&lt;/li&gt;&lt;li&gt;User Agent Switcher&lt;/li&gt;&lt;li&gt;Web Developer&lt;/li&gt;&lt;li&gt;YSlow&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Happy browsing, everyone!&lt;/p&gt;&lt;p&gt;PS: I also installed &lt;a href="http://www.skype.com/"&gt;Skype 4.0&lt;/a&gt; and it is very sleek!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-4094668221553128471?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/4094668221553128471/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=4094668221553128471' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4094668221553128471'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4094668221553128471'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/06/firefox-3.html' title='Firefox 3'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3123/2592405482_788e39f394_t.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-8306061782884542685</id><published>2008-06-07T17:20:00.004+10:00</published><updated>2008-12-10T17:13:51.502+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='social'/><category scheme='http://www.blogger.com/atom/ns#' term='virtual'/><category scheme='http://www.blogger.com/atom/ns#' term='news'/><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='exitreality'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>ExitReality goes to Beta</title><content type='html'>&lt;a href="http://www.exitreality.com/"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://3.bp.blogspot.com/_PDUXIgOmBNo/SEo90aqxjSI/AAAAAAAAAH0/8yDVF7k5_Ro/s400/exitreality.jpg" alt="" id="BLOGGER_PHOTO_ID_5209043889728621858" border="0" /&gt; ExitReality&lt;/a&gt; finally &lt;a href="http://blog.exitreality.com/"&gt;flicked the switch this week and went to Beta&lt;/a&gt;.&lt;br /&gt;&lt;blockquote&gt;ExitReality is an exciting new social media platform that aims to improve your online experience with an enhanced 3D, multi-user, immersive messaging environment.&lt;/blockquote&gt;&lt;br /&gt;Duncan Riley reported on TechCrunch in &lt;a href="http://www.techcrunch.com/2008/04/16/exitreality-turns-social-network-profiles-into-3d-spaces/"&gt;ExitReality Turns Social Network Profiles Into 3D Spaces&lt;/a&gt; that ExitReality promises to transform the social networking experience by offering virtual versions of every social network site profile.&lt;br /&gt;&lt;br /&gt;ExitReality works with leading global social media sites Facebook, Myspace, Friendster, Hi5, Orkut and Bebo and is launching soon.&lt;br /&gt;&lt;br /&gt;As published in JDJ: &lt;a href="http://au.sys-con.com/read/577308.htm"&gt;Carl's Jr. and Hardee's Web Sites Among First to Go 3D&lt;/a&gt;&lt;br /&gt;&lt;blockquote&gt;For the initial launch, each MySpace member gets a 3D apartment that automatically includes their music, friends, comments and videos, and can be decorated in limitless ways. Using 3D avatars, a user can don a logoed jacket, meet friends at the Carl's Jr. or Hardee's virtual restaurant or invite friends over to the burger-themed social-network living room. There, they can ride a mechanical bull, like the one in the famous Western Bacon Cheeseburger ad, play the entertaining Burger Slayer game, as well as pick up 3D widgets such as TVs, arcade game machines, furniture, and even 3D living room or restaurant layouts to decorate their own pages.&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;This was also noted in Duncan Rileys' &lt;a href="http://www.techcrunch.com/2008/05/28/exitreality-launches-with-carls-jr-deal/"&gt;ExitReality Launches With Carl’s Jr Deal&lt;/a&gt;&lt;br /&gt;&lt;blockquote&gt;Another interesting aspect is the way the platform works; unlike Second Life that relies on centralized servers, the ExitReality plugin renders the page based on the details of the page, so it doesn’t need to rely on centralized servers (the only aspect that would be lost in the case of downtime would be chat). Further as users interact on and around each page, those visitors are counted in local logs, so a website owner doesn’t lose traffic; in effect this is a visual layer the browser sees but with the original content at the original page.&lt;/blockquote&gt;&lt;br /&gt;Have a look at &lt;a href="http://www.carlsjr.com/"&gt;Carl's Jr.&lt;/a&gt; or &lt;a href="http://www.hardees.com/"&gt;Hardee's&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;I have already &lt;a href="http://signup.exitreality.com/exr_signup.php"&gt;signed up&lt;/a&gt;. Have you?&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-8306061782884542685?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/8306061782884542685/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=8306061782884542685' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/8306061782884542685'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/8306061782884542685'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/06/exitreality-goes-to-beta.html' title='ExitReality goes to Beta'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_PDUXIgOmBNo/SEo90aqxjSI/AAAAAAAAAH0/8yDVF7k5_Ro/s72-c/exitreality.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-1306604580897396198</id><published>2008-06-07T15:37:00.002+10:00</published><updated>2008-06-07T15:41:51.512+10:00</updated><title type='text'>A Blooming Great Idea</title><content type='html'>As &lt;a href="http://blog.guykawasaki.com/"&gt;Guy Kawasaki&lt;/a&gt; said about this &lt;a href="http://blog.guykawasaki.com/2008/06/a-blooming-grea.html"&gt;blooming great idea&lt;/a&gt;:&lt;br /&gt;&lt;br /&gt;&lt;blockquote&gt;This is a cool idea. I would buy one in a second. No picture. You have to trust me and click &lt;a href="http://www.design21sdn.com/competitions/11/entries/3147/gallery/18793"&gt;here&lt;/a&gt;...&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-1306604580897396198?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/1306604580897396198/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=1306604580897396198' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1306604580897396198'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1306604580897396198'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/06/blooming-great-idea.html' title='A Blooming Great Idea'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-4408162885764784538</id><published>2008-06-01T13:15:00.003+10:00</published><updated>2008-06-20T14:58:56.143+10:00</updated><title type='text'>Open Letter To CityRail</title><content type='html'>&lt;h2 id="q0v_0"&gt;I. No Choice&lt;/h2&gt; I live in Ashfield, an inner West suburb of Sydney. My daily job is in city CBD, to which I commute by train. And I don't have a choice.&lt;br id="beoy0"&gt; &lt;br id="beoy1"&gt; With winter approaching, weather prevents me from doing my daily 10km bike ride. Mornings are too chilly and evenings dark already to be fun.&lt;br id="beoy2"&gt; &lt;br id="beoy3"&gt; Riding buses in Sydney was never enjoyable. At least for me. Trains are a much better option. If you can pick your train. I take a new so-called Millennium train, which were introduced during 2000 Sydney Olympics. These are joy! I make an extra effort to catch my train every morning, just so I don't have to take the old one that comes after. I cannot believe that lots of these rusty cans still operate. Small windows, malfunctioning doors, no air-conditioning.&lt;br id="vwh91"&gt; &lt;h2 id="fyyj0"&gt;II. The Problem&lt;/h2&gt; Recently &lt;a title="CityRail" href="http://www.cityrail.info/" id="nkjx"&gt;CityRail&lt;/a&gt; introduced &lt;a title="a trial of 14-day tickets" href="http://www.cityrail.info/news/080507-14-day_ticket.jsp" id="h26m"&gt;a trial of 14 Day RailPass tickets&lt;/a&gt;. As they claim, these should reduce the ticket queues on Monday mornings.&lt;br id="fyyj1"&gt; &lt;br id="fyyj2"&gt; I can tell you that 14-day tickets are to fail. And I will tell you why.&lt;br id="evci0"&gt; &lt;br id="evci1"&gt; A return ticket to city costs me &lt;b id="j1bf0"&gt;$6.80&lt;/b&gt; or $3.40 each way. Price of a weekly ticket is $28; a slight saving versus $34 ($6.80 x 5 - majority of people don't commute everyday, mostly Monday to Friday). So this brings the cost of my daily commute down to &lt;b id="j1bf1"&gt;$5.60&lt;/b&gt;. 14-day ticket costs the same as two weekly tickets. So, you don't save money. Only thing you save is standing in the queue every other Monday morning. Actually it is costing a bit more. The interest that those 28 bucks could earn you in the bank now goes to CityRail. In other words, you are paying extra for the privilege to skip the queue half of the time.&lt;br id="xi830"&gt; &lt;br id="xi831"&gt; Weeklies have another perk attached. If you purchase your ticket after 3PM you get to use it that day and seven consecutive days. I buy weekly tickets and I use this feature to my advantage. I buy a single way ticket in the morning for $3.40. In the afternoon I purchase a weekly ticket for $28 that will take me home that day and seven more days. A total of $31.40 ($3.40 + $28) for six days &lt;b id="j1bf2"&gt;$5.23&lt;/b&gt; each (it is eight days, but as I said I don't use it on weekends, &lt;i id="xt8d0"&gt;e.g. Mon-Fri, plus Monday&lt;/i&gt;). Another benefit that you may not realise straight away is that doing it this way you get to work in 8-day cycles, which means you buy ticket on a different day every week. You start with the long queue on Monday. The following week it gets better, because you are buying your ticket on Tuesday. Next week on Wednesday, then Thursday, then Friday.&lt;br id="b9l.0"&gt; &lt;br id="b9l.1"&gt; Then when you buy your ticket on Friday you realise that this will cover this Friday and whole next week till next Friday. And that's all you need. You don't need to travel on Saturday, nor Sunday. You don't need to waste your money on a ticket you will never use.&lt;br id="neva0"&gt; &lt;br id="neva1"&gt; Don't put an expiration date on people's money!&lt;br id="ke2x0"&gt; &lt;br id="ke2x1"&gt; The inflexibility of weekly tickets is costing us a lot of money. You fall sick and you have a weekly ticket? Or a public holiday falls on Friday? Bad luck! You paid for a ride you are not going to take. Another example is that on some nights I get to go home with my wife by car. Her business requires her to drive between the shops and if the timing is right I get to go home with her. By car. With a valid train ticket in the pocket of my jeans. Again, I paid for a ride I am not going to take. I cannot tell you how much money CityRail owes me this way.&lt;br id="c1490"&gt; &lt;h2 id="xlf30"&gt;III. The Solution&lt;/h2&gt; I honestly believe that we need to shift from obsolete weekly tickets to something more flexible. The time is right, the technology is here. There is nothing stopping us from doing so. Well, unless this is what CityRail wants and this is the way they want to make extra cash.&lt;br id="fhka0"&gt; &lt;br id="fhka1"&gt; To me, a 10-ride ticket would be well suited. It would be really great! I would not have to worry about long queues on Monday mornings as I would be able to buy this ticket at any time, anywhere. I would not have to worry about losing my hard-earned cash, as the ticket would be still valid, even if I don't use it because I fell sick or used other means of transport.&lt;br id="tumf0"&gt; &lt;br id="tumf1"&gt; 10-ride tickets are already used by bus services around Sydney. I don't ride buses but I can image that these tickets are widely used.&lt;br id="co530"&gt; &lt;br id="co531"&gt; &lt;a id="ka2j0" href="http://www.flickr.com/photos/hanuska/2282287859/" target="_blank"&gt;&lt;img id="ss7q0" style="margin: 1em 1em 0pt 0pt; width: 153px; height: 240px; float: left;" src="http://docs.google.com/File?id=ddcv2p75_123c8sqbbdz_b"&gt;&lt;/a&gt;Just for the comparison, take a look at how our Melbourne brothers are doing it. Public transport in Melbourne are operated by &lt;a title="Connex" href="http://www.connexmelbourne.com.au/" id="yf4."&gt;Connex&lt;/a&gt;. &lt;br id="kaqf1"&gt; &lt;blockquote id="wtsj0"&gt;Metcards connect all train, tram and bus services for easy travel throughout Melbourne. Prices depend on the zones you travel in, the type of ticket you choose and whether you hold any concessions.&lt;br id="kaqf2"&gt; &lt;/blockquote&gt; Melbourne is divided into two zones (used to be three when I lived there five years ago). You can buy a &lt;a title="2-hour ticket" href="http://www.connexmelbourne.com.au/index.php?id=63" id="wdqy"&gt;2-hour ticket&lt;/a&gt; for a single zone (&lt;b id="qiz60"&gt;$3.50&lt;/b&gt; zone 1 or $2.70 zone 2) or both of them. You can also buy a City Saver - 10 x 2-hour ticket for &lt;b id="qiz61"&gt;$20.80&lt;/b&gt;, which is cheaper than if you buy ten separate 2-hour tickets. &lt;i id="l72q0"&gt;(To compare with my ticket from Ashfield: &lt;b id="zstm0"&gt;$3.40&lt;/b&gt; single, &lt;b id="zstm1"&gt;$28&lt;/b&gt; weekly. If I purchased a zoned ticket, it would be a Red &lt;a title="TravelPass" href="http://www.cityrail.info/fares/travelpass.jsp" id="m:ro"&gt;TravelPass&lt;/a&gt; for &lt;b id="zstm2"&gt;$35&lt;/b&gt;) &lt;/i&gt;The ticket, after being validated, is valid for the minutes to the whole hour and then two hours. This works out to be up to 2 hours and 59 minutes, if you validate it one minute after the hour. If you are lucky and live in one of the inner suburbs, 2-hour ticket gives you plenty of time to get to the city, do some shopping or whatever and come back home on a single ticket. Another great feature of these tickets is that after 7PM they remain valid until the last train service that day. Can you imagine that you could go out with your friends, move around the town, go to a restaurant in the city, then go for a walk on the beach and all of this on a single train ticket. I don't want to imagine how much I would have to fork out for this in Sydney.&lt;br id="fhka2"&gt; &lt;br id="xlf31"&gt; And as I mentioned before this could be done without putting an expiration date on people's money! My five-year-old train ticket from Melbourne was still valid when I used it this year.&lt;br id="qh3e4"&gt; &lt;h2 id="az_a0"&gt;IV. The Future&lt;/h2&gt; I encourage clever people at CityRail to think about the people that use their services, only charge for what people use and make it more flexible for all of us.&lt;br id="g57n0"&gt; &lt;br id="g57n1"&gt; More and more people work from home. Telecommuting is becoming very popular as it has many benefits for the companies, for the city and environment (less pollution) as well as the employees. These people will still use your services. If nothing else, let them save money by pre-purchasing their rides.&lt;br id="l1k62"&gt; &lt;br id="qh3e5"&gt; There are people who work part-time, they do not need weekly tickets. But trust me, they are your regular customers. They use your trains same way as all of us who commute daily. They just do it less ofter. Do they really deserve to pay more for the same ride?&lt;br id="l1k61"&gt; &lt;br id="u-043"&gt; I hope to see you all soon taking a train ride with me to a brighter future!&lt;br id="fxcx0"&gt; &lt;br id="m9j90"&gt; &lt;br id="kgz00"&gt;&lt;p&gt;PS: This is what this post looks like at &lt;a href="http://wordle.net/"&gt;Wordle&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://wordle.net/gallery/02197/hanuska"&gt;&lt;img src="http://wordle.net/thumb/02197/hanuska"&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-4408162885764784538?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/4408162885764784538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=4408162885764784538' title='11 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4408162885764784538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4408162885764784538'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2008/06/i.html' title='Open Letter To CityRail'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>11</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-2501948124127532484</id><published>2007-09-19T11:38:00.000+10:00</published><updated>2007-09-19T11:49:04.080+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='news'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Happy 25th Birthday, Smiley!</title><content type='html'>&lt;p&gt;Happy birthday, Smiley! &lt;span style="font-weight:bold;"&gt;:-)&lt;/span&gt; just turned 25!&lt;/p&gt;&lt;p&gt;&lt;blockquote&gt;It was a serious contribution to the electronic lexicon.&lt;br /&gt;&lt;br /&gt;:-)&lt;br /&gt;&lt;br /&gt;Twenty-five years ago, Carnegie Mellon University professor Scott E. Fahlman says, he was the first to use three keystrokes - a colon followed by a hyphen and a parenthesis - as a horizontal "smiley face" in a computer message.&lt;/blockquote&gt;&lt;/p&gt;&lt;p&gt;Read more in the &lt;a href="http://www.smh.com.au/news/web/digital-smiley-face-turns-25/2007/09/18/1189881506137.html"&gt;Digital smiley face turns 25&lt;/a&gt; article from &lt;a href="http://www.smh.com.au/"&gt;Sydney Morning Herald&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-2501948124127532484?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/2501948124127532484/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=2501948124127532484' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/2501948124127532484'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/2501948124127532484'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/09/happy-25th-birthday-smiley.html' title='Happy 25th Birthday, Smiley!'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-353880933135677103</id><published>2007-09-13T23:05:00.000+10:00</published><updated>2008-12-10T17:13:52.181+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='social'/><category scheme='http://www.blogger.com/atom/ns#' term='quote'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>Respect</title><content type='html'>&lt;p&gt;I catch a train to Sydney CBD where I work. I notice a big difference between my morning and evening commute.&lt;/p&gt;&lt;div style="float:left;clear:left;padding:0 8px 8px 0;"&gt;&lt;div style="border:1px #000 solid;margin:0;"&gt;&lt;img style="background-color:white;border:0;padding:4px 4px 2px 4px;margin:0;" alt="" src="http://3.bp.blogspot.com/_PDUXIgOmBNo/RulF9EM_VLI/AAAAAAAAADY/S1aUV_Is_5w/s200/sydney_train_new.jpg"  /&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;Morning commute is usually a very pleasant ride. I catch a &lt;a href="http://en.wikipedia.org/wiki/CityRail"&gt;CityRail&lt;/a&gt; train that starts its trip at my station, therefore I get a seat anywhere I like. This is an all-stops train that usually waits for the express one. I really do not understand the human nature! My station is very close to the city (10km to be exact). Nevertheless, people chose to ride on an old fully packed express train, rather than all-stops brand new &lt;a href="http://en.wikipedia.org/wiki/Millennium_train"&gt;Millennium train&lt;/a&gt;, which by the way comes only five minutes after the express one.&lt;/p&gt;&lt;p&gt;That makes me think. Why would anybody choose to stand on the train, squashed between other people for 15 minutes rather than spend 20 minutes seated in comfort and doing something useful or enjoyable, like reading a book or magazine?&lt;/p&gt;&lt;div style="float:left;clear:left;padding:0 8px 8px 0;"&gt;&lt;div style="border:1px #000 solid;margin:0;"&gt;&lt;img style="background-color:white;border:0;padding:4px 4px 2px 4px;margin:0;" alt="" src="http://3.bp.blogspot.com/_PDUXIgOmBNo/RulDLEM_VKI/AAAAAAAAADQ/rPmzODQ2I5Y/s200/sydney_train_old.jpg"  /&gt;&lt;/div&gt;&lt;/div&gt;&lt;p&gt;And if I happen to miss my all-stops than seven minutes later I can catch another express train which is a brand new one and with plenty vacant seats this time.&lt;/p&gt;&lt;p&gt;I love my morning rides! They are quite. I guess most of the people are still half asleep or simply have nothing to talk about.&lt;/p&gt;&lt;p&gt;Evening rides are a whole different story. I rarely pick the train that is new - maybe I should find out what time such leave and then try to make it to the station on time. But I cannot be bothered.&lt;/p&gt;&lt;p&gt;Anyway, in the evenings people seem to chat a lot. Just yesterday I boarded the train and along my side there was an Indian guy &lt;i&gt;(no race discrimination here, all people are same)&lt;/i&gt; already on his mobile phone. Talking non-stop! (Luckily) there is no mobile coverage in the tunnel under the city so he was cut off when we left the station. As soon as we emerged back on the surface, he re-dialed and continued to talk for next 25 minutes until I arrived at my station. He probably continued talking until he reached his destination.&lt;/p&gt;&lt;p&gt;How annoying is that! I do not need to listen to other people's conversations. When I was in Japan I admired they culture. One of the things I'd appreciate here in Australia is that in Japan people do not use mobiles on the trains. It is simply impolite. They even switch the ringing to vibration mode.&lt;/p&gt;&lt;div&gt;&lt;img src="http://2.bp.blogspot.com/_PDUXIgOmBNo/RulKI0M_VMI/AAAAAAAAADg/VwRBemMp52Y/s400/millenium-train.jpg" border="0" alt="" /&gt;&lt;/div&gt;&lt;p&gt;I am annoyed by loud people who selfishly created noise that other passengers must tolerate.&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold;"&gt;It's time to fight back!&lt;/span&gt;&lt;/p&gt;&lt;p&gt;As mentioned at &lt;a href="http://ahumblejedi.wordpress.com/2007/02/03/shhh-cards/"&gt;Much Madness::Or divinest sense?&lt;/a&gt; website: &lt;/p&gt;&lt;blockquote&gt;Coudal Partners published a PDF of business card-sized printable handouts designed to be given to people when they are annoying you.&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;I wish I had some of these &lt;a href="http://www.coudal.com/shhh.php"&gt;SHHH cards&lt;/a&gt; that I could simply pass to these folks.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.coudal.com/shhhcards.pdf"&gt;&lt;img style="border:1px #000 solid;background-color:white;padding:4px;margin:0;" alt="" src="http://1.bp.blogspot.com/_PDUXIgOmBNo/RulOekM_VNI/AAAAAAAAADo/Hane9eHkqbw/s400/coudalshh.jpg"  /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-353880933135677103?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/353880933135677103/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=353880933135677103' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/353880933135677103'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/353880933135677103'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/09/respect.html' title='Respect'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_PDUXIgOmBNo/RulF9EM_VLI/AAAAAAAAADY/S1aUV_Is_5w/s72-c/sydney_train_new.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-6723948383692674532</id><published>2007-08-27T23:22:00.000+10:00</published><updated>2007-08-27T23:43:00.621+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='findbugs'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='quote'/><category scheme='http://www.blogger.com/atom/ns#' term='puzzler'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Java Puzzlers, Episode 6</title><content type='html'>&lt;p&gt;I am a big fan of &lt;a href="http://www.javapuzzlers.com/"&gt;Java Puzzlers&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Another part of the Java Puzzler series appeared on Google Video couple days ago. This is one named &lt;a href="http://video.google.com/videoplay?docid=9214177555401838409"&gt;Advanced Topics in Programming Languages: Java Puzzlers, Episode VI&lt;/a&gt; and is a repeat of a talk given at Google in May and at JavaOne 2007.&lt;/p&gt;&lt;p&gt;&lt;blockquote&gt;Josh Bloch and special guest star Bill Pugh present yet another installment in the continuing saga of Java Puzzlers, consisting of eight more programming puzzles for your entertainment and enlightenment.&lt;/blockquote&gt;&lt;/p&gt;&lt;p&gt;I really enjoyed watching it and also learnt a thing or two.&lt;/p&gt;&lt;p&gt;Funny thing was when Bill Pugh said in the conclusion:&lt;/p&gt;&lt;p&gt;&lt;blockquote&gt;Use FindBugs: it finds all 8 bugs in this talk!&lt;/blockquote&gt;&lt;/p&gt;&lt;p&gt;I use &lt;a href="http://findbugs.sourceforge.net/"&gt;FindBugs&lt;/a&gt; everyday and I have to tell you, our codebase &lt;i&gt;(JIRA)&lt;/i&gt; is quite clean and FindBugs helps us to keep it that way.&lt;/p&gt;&lt;p&gt;Alright! Enough said. Go on! Watch it!&lt;/p&gt;&lt;p&gt;&lt;embed style="width:400px; height:326px;" id="VideoPlayback" type="application/x-shockwave-flash" src="http://video.google.com/googleplayer.swf?docId=9214177555401838409&amp;hl=en-AU" flashvars=""&gt; &lt;/embed&gt;&lt;/p&gt;&lt;p&gt;Related posts: &lt;a href="http://hanuska.blogspot.com/2006/03/java-puzzlers.html"&gt;Java Puzzlers&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-6723948383692674532?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/6723948383692674532/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=6723948383692674532' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6723948383692674532'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6723948383692674532'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/08/java-puzzlers-episode-6.html' title='Java Puzzlers, Episode 6'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-8961153272324492688</id><published>2007-08-26T13:03:00.000+10:00</published><updated>2007-08-26T13:15:40.625+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='collections'/><category scheme='http://www.blogger.com/atom/ns#' term='element'/><title type='text'>Contract of the interfaces</title><content type='html'>&lt;p&gt;As I mentioned in my previous post titled &lt;a href="http://hanuska.blogspot.com/2006/04/dont-test-everything.html"&gt;Don't test everything&lt;/a&gt;, unit testing is very valuable in the software development process, but on some occasions the test expects more that it should. In some cases those expectation work fine, in other they fail.&lt;/p&gt;&lt;p&gt;What the hell am I talking about? If you follow the good practice of coding against interfaces, you know that the interface defines the contract all implementation classes must adhere to. If you write an implementation of an interface your unit tests should test possibly everything that this contract specifies and nothing more.&lt;/p&gt;&lt;p&gt;Take a &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Set.html"&gt;Set&lt;/a&gt; from &lt;a href="http://java.sun.com/j2se/1.5.0/docs/guide/collections/index.html"&gt;Java Collections Framework&lt;/a&gt; for example. This interface is defined as: &lt;blockquote&gt;A collection that contains no duplicate elements. More formally, sets contain no pair of elements e1 and e2 such that e1.equals(e2), and at most one null element. As implied by its name, this interface models the mathematical set abstraction.&lt;/blockquote&gt;&lt;/p&gt;&lt;p&gt;At some point I had a unit test that had some input values and my test was assuming the correct results in the set that was returned. I knew that my implementation wa returning a &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/HashSet.html"&gt;HashSet&lt;/a&gt; and I also knew what was in that set. The asserts were quite simple (the code is simplified):&lt;/p&gt;&lt;pre style="color:blue;"&gt;String[] addresses = new String[] {"address1", "address2", "address3"};&lt;br /&gt;Set set = new HashSet(Arrays.asList(addresses));&lt;br /&gt;Iterator i = set.iterator();&lt;br /&gt;assertEquals("address1", i.next());&lt;br /&gt;assertEquals("address2", i.next());&lt;br /&gt;assertEquals("address3", i.next());&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;It's a good test, you may think. Well, it isn't! This test runs or fails depending on which JDK you use. The problem with this test is that it assumes the order of the elements in the returning set. Set interface does not guarantee the order of its elements. We should not test that.&lt;/p&gt;&lt;p&gt;Let's have a look at the following unit test&lt;/p&gt;&lt;pre style="color:blue;"&gt;import junit.framework.TestCase;&lt;br /&gt;&lt;br /&gt;import java.util.Set;&lt;br /&gt;import java.util.Arrays;&lt;br /&gt;import java.util.HashSet;&lt;br /&gt;import java.util.Iterator;&lt;br /&gt;&lt;br /&gt;public class TestJdkDiff extends TestCase&lt;br /&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;public void testOrder()&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String javaVersion = System.getProperty("java.version");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String javaVendor = System.getProperty("java.vendor");&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;System.out.println("Running " + javaVendor + " " + javaVersion);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;String[] addresses = new String[] {"address1", "address2", "address3"};&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;final Set set = new HashSet(Arrays.asList(addresses));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;for (Iterator i = set.iterator(); i.hasNext();)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;System.out.println(i.next());&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Execution of the previous test on Java 6 produces the following output&lt;/p&gt;&lt;pre style="color:green;"&gt;Running Sun Microsystems Inc. 1.6.0_02&lt;br /&gt;address1&lt;br /&gt;address2&lt;br /&gt;address3&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;The same test executed on Sun's JVM 1.4 prints out&lt;/p&gt;&lt;pre style="color:green;"&gt;Running Sun Microsystems Inc. 1.4.2_12&lt;br /&gt;address2&lt;br /&gt;address3&lt;br /&gt;address1&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Oops! Now I know why my test failed. Even, in JDK the implementation of some classes can change from time to time. As long as the contact is kept all should be fine.&lt;/p&gt;&lt;p&gt;So to fix my initial test one should write&lt;/p&gt;&lt;pre style="color:blue;"&gt;String[] addresses = new String[] {"address1", "address2", "address3"};&lt;br /&gt;Set set = new HashSet(Arrays.asList(addresses));&lt;br /&gt;assertEquals(3, set.size());&lt;br /&gt;assertTrue(set.contains("address1"));&lt;br /&gt;assertTrue(set.contains("address2"));&lt;br /&gt;assertTrue(set.contains("address3"));&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Happy coding!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-8961153272324492688?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/8961153272324492688/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=8961153272324492688' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/8961153272324492688'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/8961153272324492688'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/08/contract-of-interfaces.html' title='Contract of the interfaces'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-4003610896539078538</id><published>2007-08-16T21:15:00.000+10:00</published><updated>2007-08-16T21:32:56.792+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='best practice'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>Keep it simple</title><content type='html'>&lt;p&gt;Recently I saw pieces of code that could be simplified. I see such code often, however, recently I came across code that seemed to follow the same pattern&lt;/p&gt;&lt;p&gt;The patern was as in the following example:&lt;/p&gt;&lt;pre style="color:blue;"&gt;&lt;br /&gt;private boolean someFlag;&lt;br /&gt;&lt;br /&gt;...&lt;br /&gt;&lt;br /&gt;public boolean isSomeFlagSet() {&lt;br /&gt;  if (someFlag) {&lt;br /&gt;    return true;&lt;br /&gt;  }&lt;br /&gt;  else {&lt;br /&gt;    return false;&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Why not simply write:&lt;/p&gt;&lt;pre style="color:green;"&gt;&lt;br /&gt;public boolean isSomeFlagSet() {&lt;br /&gt;  return someFlag;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;It is so much simpler!&lt;/p&gt;&lt;p&gt;Similarly to boolean flags, there where occurencies of other object types being used and methods invoked on them in the following manner:&lt;/p&gt;&lt;pre style="color:blue;"&gt;&lt;br /&gt;public String getCity() {&lt;br /&gt;  if (address == null) {&lt;br /&gt;    return null;&lt;br /&gt;  }&lt;br /&gt;  else {&lt;br /&gt;    return address.getCity();&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;This can be also simplified (applying "change if-else to ?:" refactoring) to:&lt;/p&gt;&lt;pre style="color:green;"&gt;&lt;br /&gt;public String getCity() {&lt;br /&gt;  return address == null ? null : address.getCity();&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Please strive for simplicity in your code (&lt;a href="http://en.wikipedia.org/wiki/KISS_principle"&gt;K.I.S.S. principle&lt;/a&gt;). Verbosity clutters the code and can hide the meaning or intention of it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-4003610896539078538?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/4003610896539078538/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=4003610896539078538' title='17 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4003610896539078538'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4003610896539078538'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/08/keep-it-simple.html' title='Keep it simple'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>17</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-4864941984577328984</id><published>2007-08-12T21:41:00.000+10:00</published><updated>2007-08-26T12:43:57.289+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><title type='text'>ArithmeticException vs. NaN</title><content type='html'>&lt;p&gt;Recently  I worked on a small UI widget that renders bars that represent percentage. The percentage could be calculated by a simple formula such as the following:&lt;p&gt;&lt;p style="text-align:center;"&gt;percentage = value / total * 100%&lt;/p&gt;&lt;p&gt;Imagine a utility method that calculates the percentage and looks like the following:&lt;/p&gt;&lt;p&gt;&lt;pre style="font-family: Courier New; color: blue;"&gt;public static int calcPercentage(int value, int total) {&lt;br /&gt;  return 100 * value / total;&lt;br /&gt;}&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;You could say that this is a fairly simple method and would not be that hard to unit test it. Assuming that the given parameters will never be negative numbers one could whip up a sample test values very quickly.&lt;/p&gt;&lt;p&gt;&lt;pre style="font-family: Courier New; color: blue;"&gt;public void testCalPercentage() {&lt;br /&gt;  assertEquals(0, calcPercentage(0, 2));&lt;br /&gt;  assertEquals(33, calcPercentage(1, 2));&lt;br /&gt;  assertEquals(50, calcPercentage(2, 2));&lt;br /&gt;}&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;Take a bunch of positive numbers or zeros... Wait! Zeros?! But there could be a possible division by zero! That's right! There is our edge case. Let's test it! Aha! We now get an &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/ArithmeticException.html"&gt;ArithmeticException&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;pre style="font-family: Courier New; color: blue;"&gt;public void testCalPercentageDivisionByZero() {&lt;br /&gt;  try {&lt;br /&gt;    assertEquals(0, calcPercentage(0, 0));&lt;br /&gt;    fail();&lt;br /&gt;  }&lt;br /&gt;  catch (ArithmeticException ex) {&lt;br /&gt;    // expected&lt;br /&gt;  }&lt;br /&gt;}&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;That's understandable. So we need to work around this and the bar should not be rendered if not values (zeros) were entered.&lt;/p&gt;&lt;p&gt;And here comes the twist! Change the type of spent and remaining variables from primitive int to primitive float.&lt;/p&gt;&lt;p&gt;&lt;pre style="font-family: Courier New; color: blue;"&gt;public static int calcPercentage(float value, float total) {&lt;br /&gt;  return (int) (100 * value / total);&lt;br /&gt;}&lt;/pre&gt;&lt;/p&gt;&lt;p&gt;No exception is thrown anymore. What happened? Why such a different behavior?&lt;p&gt;&lt;p&gt;It all boils down to how Java and other programming languages handle float point arithmetic. I hope that the following &lt;a href="http://www.artima.com/underthehood/floating.html"&gt;quote&lt;/a&gt; sums it all.&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;Floating-point numbers in the JVM use a radix of two. Floating-point numbers in the JVM, therefore, have the following form:&lt;/p&gt;&lt;p style="text-align:center"&gt;sign * mantissa * 2 exponent&lt;/p&gt;&lt;p&gt;The mantissa of a floating-point number in the JVM is expressed as a binary number. A normalized mantissa has its binary point (the base-two equivalent of a decimal point) just to the left of the most significant non-zero digit. Because the binary number system has just two digits -- zero and one -- the most significant digit of a normalized mantissa is always a one.&lt;/p&gt;&lt;p&gt;The most significant bit of a float or double is its sign bit. The mantissa occupies the 23 least significant bits of a float and the 52 least significant bits of a double. The exponent, 8 bits in a float and 11 bits in a double, sits between the sign and mantissa. The format of a float is shown below. The sign bit is shown as an "s," the exponent bits are shown as "e," and the mantissa bits are shown as "m":&lt;/p&gt;&lt;p style="text-align:center;"&gt;&lt;table style="border:1px;padding:10px;"&gt;&lt;tr&gt;&lt;th style="font-weight:bold; text-align:center;"&gt;Bit layout of Java float&lt;/th&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;s eeeeeeee mmmmmmmmmmmmmmmmmmmmmmm&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;&lt;p&gt;The exponent field is interpreted in one of three ways. An exponent of all ones indicates the floating-point number has one of the special values of plus or minus infinity, or "not a number" (NaN). NaN is the result of certain operations, such as the division of zero by zero. An exponent of all zeros indicates a denormalized floating-point number. Any other exponent indicates a normalized floating-point number.&lt;/p&gt;&lt;p&gt;The JVM throws no exceptions as a result of any floating-point operations. Special values, such as positive and negative infinity or NaN, are returned as the result of suspicious operations such as division by zero. An exponent of all ones indicates a special floating-point value. An exponent of all ones with a mantissa whose bits are all zero indicates an infinity. The sign of the infinity is indicated by the sign bit. An exponent of all ones with any other mantissa is interpreted to mean "not a number" (NaN). The JVM always produces the same mantissa for NaN, which is all zeros except for the most significant mantissa bit that appears in the number. These values are shown for a float below:&lt;/p&gt;&lt;p&gt;&lt;table&gt;&lt;tr&gt;&lt;td colspan="2" style="font-weight:bold; text-align:center;"&gt;Special float values&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td style="font-weight:bold; text-align:center;"&gt;Value&lt;/td&gt;&lt;td style="font-weight:bold; text-align:center;"&gt;Float bits (sign exponent mantissa)&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;+Infinity&lt;/td&gt;&lt;td&gt;0 11111111 00000000000000000000000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;-Infinity&lt;/td&gt;&lt;td&gt;1 11111111 00000000000000000000000&lt;/td&gt;&lt;/tr&gt;&lt;tr&gt;&lt;td&gt;NaN&lt;/td&gt;&lt;td&gt;1 11111111 10000000000000000000000&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/p&gt;&lt;br /&gt;&lt;/blockquote&gt;&lt;p&gt;Things like these we learn when we learn computer programming and tend to forget over time. And then... a simple percentage calculation will remind us.&lt;/p&gt;&lt;p&gt;Happy coding!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-4864941984577328984?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/4864941984577328984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=4864941984577328984' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4864941984577328984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4864941984577328984'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/08/arithmeticexception-vs-nan.html' title='ArithmeticException vs. NaN'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-1313847722001778063</id><published>2007-07-25T19:54:00.000+10:00</published><updated>2008-12-10T17:13:52.361+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jira'/><category scheme='http://www.blogger.com/atom/ns#' term='gadget'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>JIRA Issues Gadget 1.2 Released</title><content type='html'>&lt;p&gt;I am proud to announce the release of JIRA Issues Gadget 1.2. This point release includes two bug fixes and an improvement in the way summary information is displayed.&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_PDUXIgOmBNo/RqcgidseVFI/AAAAAAAAADA/WDHBvz8h05M/s1600-h/jira-issues-gadget-1.2-preview.jpg"&gt;&lt;img style="cursor:pointer; cursor:hand;" src="http://1.bp.blogspot.com/_PDUXIgOmBNo/RqcgidseVFI/AAAAAAAAADA/WDHBvz8h05M/s400/jira-issues-gadget-1.2-preview.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5091073680224441426" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;Try it now&lt;/h4&gt;&lt;p&gt;&lt;a href="http://fusion.google.com/ig/add?synd=open&amp;source=&amp;amp;moduleurl=http://dushan.hanuska.googlepages.com/jira-issues.xml"&gt;&lt;img src="http://buttons.googlesyndication.com/fusion/add.gif" style="border: 0pt none ;" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;New Features&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Overall improvement of the way summary information is displayed and well as truncation of long summaries. Changed CSS in order to auto-hide part of the summary that overflows.&lt;/li&gt;&lt;li&gt;Added a pop-up tooltip that displays more information about the issue. The information displayed is: &lt;b&gt;issue key&lt;/b&gt;, &lt;b&gt;type&lt;/b&gt;, &lt;b&gt;status&lt;/b&gt;, &lt;b&gt;resolution&lt;/b&gt; and full length &lt;b&gt;summary&lt;/b&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;h4&gt;Bug Fixes&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Removed 'maxSummaryLength' user preference as it is no longer required.&lt;/li&gt;&lt;li&gt;Links on summaries did not work properly on Firefox with Redirect Remover add-on. With the summary improvements this is no longer an issue.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;h4&gt;Links&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://dushan.hanuska.googlepages.com/jiraissuesgadget"&gt;JIRA Issues Gadget Homepage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/jira-gadgets/"&gt;JIRA Issues Gadget Project Home&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.google.com/ig"&gt;Personalized Google Homepage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.atlassian.com/software/jira"&gt;Atlassian JIRA&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;h4&gt;Related posts&lt;/h4&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://hanuska.blogspot.com/2007/07/jira-issues-gadget-11-released.html"&gt;JIRA Issues Gadget 1.1 Released&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://hanuska.blogspot.com/2007/05/jira-issues-google-gadget.html"&gt;JIRA Issues Google Gadget&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-1313847722001778063?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/1313847722001778063/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=1313847722001778063' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1313847722001778063'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1313847722001778063'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/07/jira-issues-gadget-12-released.html' title='JIRA Issues Gadget 1.2 Released'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_PDUXIgOmBNo/RqcgidseVFI/AAAAAAAAADA/WDHBvz8h05M/s72-c/jira-issues-gadget-1.2-preview.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-3614848984959839993</id><published>2007-07-03T22:23:00.000+10:00</published><updated>2007-07-03T22:43:40.720+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jira'/><category scheme='http://www.blogger.com/atom/ns#' term='gadget'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>JIRA Issues Gadget 1.1 Released</title><content type='html'>&lt;p&gt;I am proud to announce the release of JIRA Issues Gadget 1.1. This point release includes two bug fixes and two improvements.&lt;/p&gt;&lt;h4&gt;Try it now&lt;/h4&gt;&lt;p&gt;&lt;a href="http://fusion.google.com/ig/add?synd=open&amp;source=&amp;amp;moduleurl=http://dushan.hanuska.googlepages.com/jira-issues.xml"&gt;&lt;img src="http://buttons.googlesyndication.com/fusion/add.gif" style="border: 0pt none ;" alt="" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;h4&gt;New Features&lt;/h4&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;Added content refresh. The frequency of refresh is customizable. This enables the gadget to poll for updates in Google Desktop, which does not automatically refresh as Google homepage does.&lt;/li&gt;&lt;li&gt;Increased the number of displayable issues to 30. This enables to see more issues if the user chooses to.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;h4&gt;Bug Fixes&lt;/h4&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;Added a message to display in case if no matching issues are found.&lt;/li&gt;&lt;li&gt;Fixed a typo in CSS text alignment.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;h4&gt;Links&lt;/h4&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://dushan.hanuska.googlepages.com/jiraissuesgadget"&gt;JIRA Issues Gadget Homepage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://code.google.com/p/jira-gadgets/"&gt;JIRA Issues Gadget Project Home&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.google.com/ig"&gt;Personalized Google Homepage&lt;/a&gt;&lt;/li&gt;&lt;li&gt;&lt;a href="http://www.atlassian.com/software/jira"&gt;Atlassian JIRA&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;h4&gt;Related posts&lt;/h4&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://hanuska.blogspot.com/2007/05/jira-issues-google-gadget.html"&gt;JIRA Issues Google Gadget&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-3614848984959839993?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/3614848984959839993/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=3614848984959839993' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/3614848984959839993'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/3614848984959839993'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/07/jira-issues-gadget-11-released.html' title='JIRA Issues Gadget 1.1 Released'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-5554197602745586174</id><published>2007-06-02T12:15:00.000+10:00</published><updated>2008-12-10T17:13:52.758+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='maps'/><category scheme='http://www.blogger.com/atom/ns#' term='australia'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='quote'/><category scheme='http://www.blogger.com/atom/ns#' term='gadget'/><category scheme='http://www.blogger.com/atom/ns#' term='gdd07'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='mashup'/><title type='text'>Google Developer Day 2007 in Sydney</title><content type='html'>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/hanuska/525660992/" title="Photo Sharing"&gt;&lt;img src="http://farm2.static.flickr.com/1187/525660992_5e0c1cad0c_m.jpg" alt="Google Developer Day 2007" style="margin: 0pt 0pt 10px 10px; float: right; border: 0;" height="192" width="240" /&gt;&lt;/a&gt;I attended Google Developer Day in Sydney this week. The &lt;a href="http://code.google.com/events/developerday/au-sessions.html" target="_blank"&gt;main page&lt;/a&gt; describes the content of the sessions in Sydney. It also links to &lt;a href="http://www.youtube.com/profile_videos?user=GoogleDeveloperDay&amp;p=r" target="_blank"&gt;related video records&lt;/a&gt; that can be viewed at &lt;a href="http://www.youtube.com/profile_videos?user=GoogleDeveloperDay&amp;amp;p=r" target="_blank"&gt;YouTube&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The event was well organized. Originally, this was meant to be a 100 people event. However due to its popularity, the event was fully booked within 20 minutes after the registration opened. Later Google decided to change the venue to &lt;a href="http://www.atp.com.au/" target="_blank"&gt;Australia Technology Park&lt;/a&gt; and were able to accommodate all people from the waiting list.&lt;/p&gt;&lt;p&gt;&lt;table&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.flickr.com/photos/hanuska/525660438/" title="Photo Sharing"&gt;&lt;img src="http://farm2.static.flickr.com/1204/525660438_a0f4739bf6_m.jpg" alt="Google Developer Day 2007" height="180" width="240" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.flickr.com/photos/hanuska/525706915/" title="Photo Sharing"&gt;&lt;img src="http://farm2.static.flickr.com/1062/525706915_98627f5301_m.jpg" alt="Google Developer Day 2007" height="180" width="240" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;p&gt;&lt;a href="http://gears.google.com/"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right;" src="http://1.bp.blogspot.com/_PDUXIgOmBNo/RmJcbr56RDI/AAAAAAAAACY/w8uYj3tf7T8/s200/gears_sm.png" alt="" id="BLOGGER_PHOTO_ID_5071717761084441650" border="0" /&gt;&lt;/a&gt;One of the biggest announcements was &lt;a href="http://gears.google.com/" target="_blank"&gt;Google Gears (BETA)&lt;/a&gt;. It is available for Windows, Mac and Linux. Google Gears is an open source technology for creating offline web applications. As published in &lt;a href="http://www.smh.com.au/news/biztech/google-unveils-gears-technology/2007/05/31/1180205350391.html?s_cid=rss_technology" target="_blank"&gt;Sydney Morning Herald&lt;/a&gt;:&lt;/p&gt;&lt;blockquote&gt;The Gears technology promises to give Google a better platform from which to go after Microsoft's very lucrative Office franchise.&lt;/blockquote&gt;&lt;p&gt;Here is a blog post that will &lt;a href="http://immike.net/blog/2007/05/31/getting-started-with-google-gears/" target="_blank"&gt;get you started&lt;/a&gt; with Gears.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.panoramio.com/"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right;" src="http://4.bp.blogspot.com/_PDUXIgOmBNo/RmJefb56REI/AAAAAAAAACg/4t7GiBS0zEY/s200/panoramio-sm.png" alt="" id="BLOGGER_PHOTO_ID_5071720024532206658" border="0" /&gt;&lt;/a&gt;Another announcement of the day was &lt;a href="http://google-latlong.blogspot.com/2007/05/google-to-purchase-panoramio.html" target="_blank"&gt;Google's purchase&lt;/a&gt; of &lt;a href="http://www.panoramio.com/" target="_blank"&gt;Panoramio&lt;/a&gt;, a website that links millions of photos with the exact location where they were taken.&lt;/p&gt;&lt;p&gt;&lt;a href="http://code.google.com/webtoolkit/"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: right;" src="http://2.bp.blogspot.com/_PDUXIgOmBNo/RmJQr756RCI/AAAAAAAAACQ/eXxgoD9WPWc/s200/gwt-box-150.png" alt="" id="BLOGGER_PHOTO_ID_5071704846117782562" border="0" /&gt;&lt;/a&gt;&lt;a href="http://www.blogger.com/post-create.g?blogID=23939980" target="_blank"&gt;Google Web Toolkit&lt;/a&gt; (GWT) got an upgrade as well. &lt;span style="font-weight: bold;"&gt;GTW 1.4 Release Candidate&lt;/span&gt; is a major upgrade to the Google’s open-source framework for writing AJAX web applications in the Java programming language. Read more about its features at ZDNet blog post by Ed Burnette: &lt;a href="http://blogs.zdnet.com/Burnette/?p=322" target="_blank"&gt;Google Web Toolkit 1.4: "Have to see it to believe it"&lt;/a&gt;.&lt;/p&gt;&lt;blockquote&gt;Google Web Toolkit had brought Google's AJAX development out of the dark ages and into the 21st century.&lt;/blockquote&gt;&lt;p&gt;said Lars Rasmussen in his &lt;a href="http://apcmag.com/6247/ajax_is_painful_painful_painful_says_google" target="_blank"&gt;AJAX is painful, painful, painful&lt;/a&gt; talk.&lt;/p&gt;&lt;p&gt;Also announced was &lt;a href="http://editor.googlemashups.com/editor" target="_blank"&gt;Google Mashup Editor&lt;/a&gt; - experimental product, online application to create mashups. It is currently in beta and access is limited to small number of developers during this testing period.&lt;/p&gt;&lt;p&gt;A great combination of Google's APIs are &lt;a href="http://www.google.com/apis/maps/documentation/mapplets/" target="_blank"&gt;Google Mapplets&lt;/a&gt;. They are mini-applications that you can embed within the Google Maps site. Then they can manipulate the map using Javascript calls that are derived from the Google Maps API. The &lt;a href="http://maps.google.com/preview" target="_blank"&gt;preview maps site&lt;/a&gt; also has &lt;strong&gt;Street View&lt;/strong&gt;, which is very cool and was enabled just few days before Google Dev Day.&lt;/p&gt;&lt;p&gt;When we arrived we received a "speedgeeking" card, which listed six URLs of Google mashups. These six sites were presented live on big screens in the lunch area where everybody had a chance to see the products, talk to the authors and cast one's vote. At the end of the day, &lt;a href="http://www.propertyguru.com.au/" target="_blank"&gt;Property Guru&lt;/a&gt; took the prize home.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/hanuska/527260688/" title="Photo Sharing"&gt;&lt;img src="http://farm2.static.flickr.com/1222/527260688_c29a69aa4e_m.jpg" alt="Google Developer Day 2007" style="margin: 0pt;" height="240" width="238" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;And if it was not Google, there would be no search. I was strongly reminded that Google is the company behind the most popular search engine when I saw this card  on the tables.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/hanuska/527352371/" title="Photo Sharing"&gt;&lt;img style="margin: 0pt;" src="http://farm1.static.flickr.com/237/527352371_54459f2e79_m.jpg" alt="Google Developer Day 2007 tag" height="141" width="240" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;So there you go Google! I blogged and published my photos with &lt;strong&gt;GDD07&lt;/strong&gt; tag. Go and find me!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-5554197602745586174?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/5554197602745586174/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=5554197602745586174' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/5554197602745586174'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/5554197602745586174'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/06/google-developer-day-2007-in-sydney.html' title='Google Developer Day 2007 in Sydney'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm2.static.flickr.com/1187/525660992_5e0c1cad0c_t.jpg' height='72' width='72'/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-670334531090256434</id><published>2007-05-31T19:12:00.000+10:00</published><updated>2007-06-03T21:53:27.452+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='gdd07'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Google Gears released today</title><content type='html'>&lt;p&gt;&lt;a href="http://gears.google.com/" target="_blank"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left;" src="http://gears.google.com/images/gears_sm.png" alt="Google Gears" border="0" /&gt;&lt;/a&gt; Google released &lt;a href="http://gears.google.com/" target="_blank"&gt;Gears (Beta)&lt;/a&gt; today. This news was brought to the world audience at &lt;a href="http://code.google.com/events/developerday/" target="_blank"&gt;Google Developer Day 2007&lt;/a&gt; in Sydney.&lt;/p&gt;&lt;p&gt;More news coming later...&lt;/p&gt;&lt;p&gt;Related post: &lt;a href="http://hanuska.blogspot.com/2007/06/google-developer-day-2007-in-sydney.html"&gt;Google Developer Day 2007 in Sydney&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-670334531090256434?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/670334531090256434/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=670334531090256434' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/670334531090256434'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/670334531090256434'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/05/google-gears-released-today.html' title='Google Gears released today'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-4068562234026995611</id><published>2007-05-15T17:52:00.000+10:00</published><updated>2008-12-10T17:13:53.197+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='jira'/><category scheme='http://www.blogger.com/atom/ns#' term='fedex'/><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='gadget'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='atlassian'/><title type='text'>JIRA Issues Google Gadget</title><content type='html'>&lt;p&gt;It's been a while since my last post. You may have been wondering what I've been up to. Well, I was busy spending my free time developing my first &lt;a href="http://code.google.com/apis/gadgets/"&gt;Google Gadget&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I must say that the Google Gadgets &lt;a href="http://www.google.com/apis/gadgets/index.html"&gt;documentation&lt;/a&gt;, especially the &lt;a href="http://www.google.com/apis/gadgets/docs-home.html"&gt;Developer Guide&lt;/a&gt; are well written and easy to follow. Development itself was a smooth ride. The only hiccup I had on the way was at the beginning when I realized that my gadget was being cached and I had to figure out hot to switch caching off.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Have I read the docs from the beginning, I would have discovered the &lt;a href="http://www.google.com/apis/gadgets/tools.html#Dev_Gadget"&gt;Developer Gadget&lt;/a&gt; (developer.xml) that let's you control gadget caching.&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_PDUXIgOmBNo/RkmJq5YCoeI/AAAAAAAAACA/SxpuEUdrn48/s1600-h/jira-issues-screenshot-icons.png"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_PDUXIgOmBNo/RkmJq5YCoeI/AAAAAAAAACA/SxpuEUdrn48/s400/jira-issues-screenshot-icons.png" alt="" id="BLOGGER_PHOTO_ID_5064730626004001250" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I work with &lt;a href="http://www.atlassian.com/software/jira"&gt;JIRA&lt;/a&gt; on a daily basis. I work with it in order to keep track of issues: bugs / tasks / new features. I also work on it - meaning the source code of JIRA as I am one of the developers on JIRA team at &lt;a href="http://www.atlassian.com/"&gt;Atlassian&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Last week on Thursday and Friday we had out traditional &lt;a href="http://blogs.atlassian.com/rebelutionary/archives/000495.html"&gt;Fedex days&lt;/a&gt;. We were let loose to develop anything we wanted. There were no boundaries for creativity. For the results (useful and/or cool stuff) see our &lt;a href="http://blogs.atlassian.com/developer/"&gt;developer blog&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I decided to create a gadget that would display limited number of JIRA issues. So I finally got to finish &lt;a href="http://dushan.hanuska.googlepages.com/jiraissuesgadget"&gt;JIRA Issues Gadget 1.0&lt;/a&gt; as well as develop the &lt;a href="https://svn.atlassian.com/svn/public/contrib/jira/jira-add-to-google-plugin/"&gt;Add To Google&lt;/a&gt; JIRA plugin that would allow integration as painless as possible. I already &lt;a href="http://blogs.atlassian.com/developer/2007/05/add_to_google_plugin.html"&gt;blogged about it&lt;/a&gt; at Atlassian Developer blog.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Google Gadgets can take user preferences and persist them. My idea was to pass these in the "Add To Google" link in order to allow JIRA users to place JIRA Issues gadget on Google Homepage pre-set with current search filter in JIRA.&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_PDUXIgOmBNo/RkmJ8JYCofI/AAAAAAAAACI/jt9jIvm7rzQ/s1600-h/jira-issue-navigator-add-to-google.png"&gt;&lt;img style="cursor: pointer;" src="http://2.bp.blogspot.com/_PDUXIgOmBNo/RkmJ8JYCofI/AAAAAAAAACI/jt9jIvm7rzQ/s400/jira-issue-navigator-add-to-google.png" alt="" id="BLOGGER_PHOTO_ID_5064730922356744690" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;But them I hit the wall. &lt;a href="http://groups.google.com/group/Google-Gadgets-API/browse_thread/thread/695bbd98b68ddc89/8c22f9a6fd575ed3?lnk=gst&amp;q=preferences&amp;amp;rnum=5#8c22f9a6fd575ed3"&gt;Passing user preferences in the "Add To Google" link&lt;/a&gt; was not implemented yet.&lt;/p&gt;&lt;p&gt;Anyway, I managed to ease the pain a bit. With &lt;a href="http://blogs.atlassian.com/developer/2007/05/add_to_google_plugin.html"&gt;Add To Google (JIRA plugin)&lt;/a&gt; you won't be able to add Google Gadget with one-click operation, but you will have the URL you can copy and paste into the user preferences of the gadget.&lt;/p&gt;&lt;p&gt;At 4pm on Friday all Atlassian developers presented their hot creations to each other.&lt;/p&gt;&lt;p&gt;&lt;table border="0" cellspacing="2"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a href="http://www.flickr.com/photos/mcannonbrookes/497241656"&gt;&lt;img src="http://farm1.static.flickr.com/231/497241656_9d152cd54c_m.jpg" alt="Fedex presentations" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a href="http://www.flickr.com/photos/mcannonbrookes/497245220"&gt;&lt;img src="http://farm1.static.flickr.com/203/497245220_5e4636cdd7_m.jpg" alt="JIRA Issues Gadget on big screen" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;p&gt;For more information read &lt;a href="http://dushan.hanuska.googlepages.com/jiraissuesgadget"&gt;JIRA Issues Gadget&lt;/a&gt; page. &lt;b&gt;Add To Google&lt;/b&gt; plugin source code can be found at Atlassian's &lt;a href="https://svn.atlassian.com/svn/public/contrib/jira/jira-add-to-google-plugin/"&gt;public SVN&lt;/a&gt;.&lt;/p&gt;&lt;p style="font-size: 0.8em;"&gt;BTW: If you want to work on &lt;a href="http://www.atlassian.com/software/jira"&gt;JIRA&lt;/a&gt; or other &lt;a href="http://www.atlassian.com/"&gt;Atlassian products&lt;/a&gt;, let us know. &lt;a href="http://www.atlassian.com/about/jobs.jsp"&gt;We are hiring.&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-4068562234026995611?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/4068562234026995611/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=4068562234026995611' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4068562234026995611'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4068562234026995611'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/05/jira-issues-google-gadget.html' title='JIRA Issues Google Gadget'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_PDUXIgOmBNo/RkmJq5YCoeI/AAAAAAAAACA/SxpuEUdrn48/s72-c/jira-issues-screenshot-icons.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-6351488125501209216</id><published>2007-04-22T18:42:00.000+10:00</published><updated>2007-04-22T18:56:54.285+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='string'/><category scheme='http://www.blogger.com/atom/ns#' term='best practice'/><title type='text'>People still don't get String comparison</title><content type='html'>&lt;p&gt;How many times we have seen String comparison done using == or != operators?! Yet, people still get it wrong.&lt;/p&gt;&lt;p&gt; I have seen some &lt;a href="http://worsethanfailure.com/Articles/Soft_Coding.aspx"&gt;blog&lt;/a&gt; &lt;a href="http://grumpytech.blogspot.com/2007/04/business-rules-hard-coding-or-soft.html"&gt;posts&lt;/a&gt; recently where the authors had a good intention to show a case where hard-coding values went wrong. Unfortunately, they fell into the &lt;a href="http://blog.enrii.com/2006/03/15/java-string-equality-common-mistake/"&gt;common mistake&lt;/a&gt; of comparison of &lt;a href="http://javatechniques.com/public/java/docs/basics/string-equality.html"&gt;String references&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;So, if you really need to compare two String using &lt;code&gt;==&lt;/code&gt; or &lt;code&gt;!=&lt;/code&gt; make sure you call &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html#intern()"&gt;&lt;code&gt;String.intern()&lt;/code&gt;&lt;/a&gt; method before making comparison. Otherwise, always prefer &lt;a href="http://java.sun.com/j2se/1.4.2/docs/api/java/lang/String.html#equals(java.lang.Object)"&gt;&lt;code&gt;String.equals(String)&lt;/code&gt;&lt;/a&gt; for String comparison.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-6351488125501209216?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/6351488125501209216/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=6351488125501209216' title='8 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6351488125501209216'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6351488125501209216'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/04/people-still-dont-get-string-comparison.html' title='People still don&apos;t get String comparison'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>8</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-4374717724593346356</id><published>2007-04-22T14:17:00.000+10:00</published><updated>2008-12-10T17:13:53.508+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='boolean'/><category scheme='http://www.blogger.com/atom/ns#' term='best practice'/><title type='text'>Fail-fast vs. complete validation</title><content type='html'>&lt;p&gt;Almost all applications work with data that come from the interaction with humans or other applications. These data, however, may not necessarily meet the requirements of the accepting applications. Data must be validated.&lt;/p&gt;&lt;h2&gt;What is validation?&lt;/h2&gt;&lt;p&gt;Data entered must pass a set of validation rules in order to be recognized as valid and allowed for further processing.&lt;/p&gt;&lt;p&gt;As an example, lets take a class that has three members: &lt;code&gt;&lt;b&gt;name&lt;/b&gt;:String&lt;/code&gt;, &lt;code&gt;&lt;b&gt;created&lt;/b&gt;:Date&lt;/code&gt; and &lt;code&gt;&lt;b&gt;total&lt;/b&gt;:int&lt;/code&gt;. Our application requires that name is set (not null) and has at least three characters; created is also required and must be a date representing time before now; and total must be a non-negative integer.&lt;/p&gt;&lt;p&gt;There are two common approaches to data validation: fail-fast validation and complete validation.&lt;/p&gt;&lt;h2&gt;Fail-fast validation&lt;/h2&gt;&lt;h3&gt;How it works&lt;/h3&gt;&lt;p&gt;If any of the validation rules fails, validation is stopped and data is pronounced invalid and rejected for further processing.&lt;/p&gt;&lt;h3&gt;Output&lt;/h3&gt;&lt;p&gt;Boolean result that indicates the validity of input data: &lt;b&gt;true&lt;/b&gt; for valid, &lt;b&gt;false&lt;/b&gt; for invalid.&lt;/p&gt;&lt;h3&gt;Pros&lt;/h3&gt;&lt;p&gt;It is generally faster than complete validation as first failure terminates the execution of consecutive validation rules. Does not have the over of failure cause reporting.&lt;/p&gt;&lt;h3&gt;Cons&lt;/h3&gt;&lt;p&gt;Does not provide enough information about the cause of failure.&lt;/p&gt;&lt;h3&gt;When to use it&lt;/h3&gt;&lt;p&gt;If a simple result: true or false is enough; detailed information about the cause of failure is not required. May be suitable for cases when the source of data cannot correct the data (usually a system without human input).&lt;/p&gt;&lt;h3&gt;Example&lt;/h3&gt;&lt;p&gt;&lt;code&gt;&lt;b&gt;boolean isValid(String name, Date created, int total)&lt;/b&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Data is passed in and boolean result is returned.&lt;/p&gt;&lt;h2&gt;Complete validation&lt;/h2&gt;&lt;h3&gt;How it works&lt;/h3&gt;&lt;p&gt;Failure of a validation rule does not stop the validation process. Data is marked as invalid and rejected for further processing after completing whole validation process.&lt;/p&gt;&lt;h3&gt;Output&lt;/h3&gt;&lt;p&gt;Boolean result that indicates the validity of input data: true for valid, false for invalid. Some form of error collection that contains the information about the causes of validation failure.&lt;/p&gt;&lt;p&gt;For examples see &lt;a href="http://struts.apache.org/1.3.8/apidocs/org/apache/struts/action/ActionMessages.html"&gt;ActionMessages&lt;/a&gt; class from &lt;b&gt;Struts&lt;/b&gt; framework, &lt;a href="http://static.springframework.org/spring/docs/2.0.x/api/org/springframework/validation/Errors.html"&gt;Errors&lt;/a&gt; class from &lt;b&gt;Spring&lt;/b&gt; framework or &lt;a href="http://www.atlassian.com/software/jira/docs/api/3.8/com/atlassian/jira/util/ErrorCollection.html"&gt;ErrorCollection&lt;/a&gt; class in &lt;a href="http://www.atlassian.com/"&gt;Atlassian&lt;/a&gt; &lt;a href="http://www.atlassian.com/software/jira/"&gt;JIRA&lt;/a&gt;.&lt;/p&gt;&lt;h3&gt;Pros&lt;/h3&gt;&lt;p&gt;Provides information about the cause or causes of validation failure. This information can provide the necessary feedback for correcting the input data.&lt;/p&gt;&lt;h3&gt;Cons&lt;/h3&gt;&lt;p&gt;Slower than fail-fast validation as extra information about causes of validation failure are reported and full set of validation rules is executed independently on the validation result.&lt;/p&gt;&lt;h3&gt;When to use it&lt;/h3&gt;&lt;p&gt;When a complete set of failure causes is required. The causes of failure may provide hints to the user entering the data about how to correct the data.&lt;/p&gt;&lt;h3&gt;Example&lt;/h3&gt;&lt;p&gt;&lt;code&gt;&lt;b&gt;void validate(String name, Date created, int total, ErrorCollection errorCollection)&lt;/b&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Data is passed in along with the error collection. Method does not have to return anything &lt;i&gt;(void)&lt;/i&gt; as invalid data is indicated by the presence of errors in the error collection.&lt;/p&gt;&lt;h3&gt;Conclusion&lt;/h3&gt;&lt;p&gt;If the complex validation rule set can be broken down into separate validations per input field, these can be used in order to enhance the user experience (via JavaScript or AJAX) – they can provide a real-time feedback for the data being entered.&lt;/p&gt;&lt;p&gt;Also consider that some cases can involve several other input values in order to make a decision about validity of input data. Such case can for example be a single date value consisting on the values from three input fields &lt;i&gt;(don't do this, it's not a really good way of entering dates)&lt;/i&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_PDUXIgOmBNo/RirnXWkbeOI/AAAAAAAAABw/oLaAvubmTtc/s1600-h/date.jpg"&gt;&lt;img style="cursor: pointer;" src="http://1.bp.blogspot.com/_PDUXIgOmBNo/RirnXWkbeOI/AAAAAAAAABw/oLaAvubmTtc/s200/date.jpg" alt="" id="BLOGGER_PHOTO_ID_5056107920058185954" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;or conditionally required fields, such as the text area in the next picture is only required to be filled in if "other" is selected.&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_PDUXIgOmBNo/RirngGkbePI/AAAAAAAAAB4/VVTnwG4su5A/s1600-h/how.jpg"&gt;&lt;img style="cursor: pointer;" src="http://4.bp.blogspot.com/_PDUXIgOmBNo/RirngGkbePI/AAAAAAAAAB4/VVTnwG4su5A/s200/how.jpg" alt="" id="BLOGGER_PHOTO_ID_5056108070382041330" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Both types of validation serve their purpose. Which one you decide to use depends mostly on how much information about data being validated you really need in order to make a decision or to correct it in case of failure.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-4374717724593346356?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/4374717724593346356/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=4374717724593346356' title='6 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4374717724593346356'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4374717724593346356'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/04/fail-fast-vs-complete-validation.html' title='Fail-fast vs. complete validation'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_PDUXIgOmBNo/RirnXWkbeOI/AAAAAAAAABw/oLaAvubmTtc/s72-c/date.jpg' height='72' width='72'/><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-6338736775685051134</id><published>2007-04-19T19:38:00.000+10:00</published><updated>2008-12-10T17:13:53.750+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Google Reader just got better</title><content type='html'>&lt;p&gt;I use &lt;a href="http://www.google.com/reader/view/"&gt;Google Reader&lt;/a&gt; for reading blogs. It has become my daily chore as I need to keep track on things happening around our office (we blog internally and &lt;a href="http://blogs.atlassian.com/"&gt;externally&lt;/a&gt;) as well as other things of my interest.&lt;/p&gt;It was brought to my attention that &lt;a href="http://www.hicksdesign.co.uk/"&gt;Jon Hicks&lt;/a&gt; &lt;a href="http://www.hicksdesign.co.uk/journal/google-reader-theme"&gt;created new skin for Google Reader&lt;/a&gt;. I thought I would have a look.&lt;/p&gt;&lt;p&gt;I had to install &lt;a href="https://addons.mozilla.org/en-US/firefox/addon/2108"&gt;Stylish&lt;/a&gt; extension for Firefox first. Then I added a new style that I downloaded from Jon's website. And the result?&lt;/p&gt;&lt;p&gt;Before:&lt;br/&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_PDUXIgOmBNo/Ric8Q2kbeMI/AAAAAAAAABg/_NEgYabsOjE/s1600-h/gr1.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer;" src="http://4.bp.blogspot.com/_PDUXIgOmBNo/Ric8Q2kbeMI/AAAAAAAAABg/_NEgYabsOjE/s320/gr1.jpg" alt="" id="BLOGGER_PHOTO_ID_5055075366970554562" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;After:&lt;br/&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_PDUXIgOmBNo/Ric8aWkbeNI/AAAAAAAAABo/Y5XlR80Dw_w/s1600-h/gr2.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer;" src="http://2.bp.blogspot.com/_PDUXIgOmBNo/Ric8aWkbeNI/AAAAAAAAABo/Y5XlR80Dw_w/s320/gr2.jpg" alt="" id="BLOGGER_PHOTO_ID_5055075530179311826" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;b&gt;I absolutely love it!&lt;/b&gt;&lt;/p&gt;&lt;p&gt;It has made reading blogs so much better. Why don't you give it a try?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-6338736775685051134?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/6338736775685051134/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=6338736775685051134' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6338736775685051134'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6338736775685051134'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/04/google-reader-just-got-better.html' title='Google Reader just got better'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_PDUXIgOmBNo/Ric8Q2kbeMI/AAAAAAAAABg/_NEgYabsOjE/s72-c/gr1.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-4615412209883129049</id><published>2007-04-18T07:59:00.000+10:00</published><updated>2007-04-18T08:12:53.496+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='microformats'/><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><category scheme='http://www.blogger.com/atom/ns#' term='user'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Blog Update</title><content type='html'>&lt;p&gt;I have added &lt;i&gt;&lt;b&gt;subscribe now&lt;/b&gt;&lt;/i&gt; section on the left, so now you can easily bookmark or add my blog posts Google, My Yahoo!, Newsgator, Feedlounge, Netvibes and Bloglines.&lt;/p&gt;&lt;p&gt;Another useful feature that I added is the &lt;i&gt;&lt;b&gt;browse by category&lt;/b&gt;&lt;/i&gt;, which shows the labels I used in my posts and their frequency.&lt;/p&gt;&lt;p&gt;My plan is keep improving the usability of this blog. In the next stage (if I find some free time) I'd like to add those little icons for digg, reddit and del.icio.us.&lt;/p&gt;&lt;p&gt;Lastly, if you did not know it already, my blog features &lt;a href="http://microformats.org/"&gt;microformats&lt;/a&gt;. So I guess my blog can be used as an example of &lt;a href="http://nutrun.com/weblog/how-microformats-will-simplify-the-web"&gt;how microformats will simplify the web&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-4615412209883129049?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/4615412209883129049/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=4615412209883129049' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4615412209883129049'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4615412209883129049'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/04/blog-update.html' title='Blog Update'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-5433345937256980478</id><published>2007-04-17T13:11:00.000+10:00</published><updated>2007-04-17T13:16:12.803+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><title type='text'>Codegeist II</title><content type='html'>I wanted to drop a quick, work-related note about &lt;a href="http://www.atlassian.com/codegeist/"&gt;Codegeist II&lt;/a&gt;, the second annual Atlassian plugin competition. We've put up &lt;a href="http://confluence.atlassian.com/display/CODEGEIST/Prizes"&gt;$20k in cash prizes&lt;/a&gt; and the contest is now accepting entries.&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align:center;margin:10px 0px;"&gt;&lt;img src="http://www.atlassian.com/images/codegeist-logo.gif"/&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;The same &lt;a href="http://confluence.atlassian.com/display/CODEGEIST/Atlassian+Codegeist"&gt;rules&lt;/a&gt; as last year apply -- teams of one to three people, enter as often as you like, all submissions must be BSD-licensed. All entries will become part of the open-source plugin libraries, free for anyone to use. The contest concludes May 13th. &lt;br /&gt;&lt;br /&gt;You'll find all the details on the &lt;a href="http://confluence.atlassian.com/display/codegeist"&gt;Codegeist space&lt;/a&gt; on &lt;a href="http://confluence.atlassian.com"&gt;confluence.atlassian.com&lt;/a&gt;. And stay tuned to the &lt;a href="http://blogs.atlassian.com/developer/"&gt;Atlassian Developer Blog&lt;/a&gt; for updates. &lt;br /&gt;&lt;br /&gt;If you're a developer, or you know any developers, this is a great opportunity to win some great prizes. We had some great entries last year, and it was fun handing out the prizes to some smart and deserving teams. I'm looking forward to seeing what we get this year.&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-5433345937256980478?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://www.atlassian.com/codegeist/' title='Codegeist II'/><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/5433345937256980478/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=5433345937256980478' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/5433345937256980478'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/5433345937256980478'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/04/codegeist-ii.html' title='Codegeist II'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-7710926738624321840</id><published>2007-03-20T20:30:00.000+11:00</published><updated>2007-03-20T23:35:28.480+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='quote'/><category scheme='http://www.blogger.com/atom/ns#' term='user'/><category scheme='http://www.blogger.com/atom/ns#' term='best practice'/><category scheme='http://www.blogger.com/atom/ns#' term='expectation'/><title type='text'>Managing User Expectations</title><content type='html'>&lt;p&gt;One of the last chapters of &lt;a href="http://www.pragmaticprogrammer.com/ppbook/index.shtml"&gt;The Pragmatic Programmer: From Journeyman to Master&lt;/a&gt; book that I finished reading today is titled &lt;i&gt;"Great Expectations"&lt;/i&gt;.&lt;/p&gt;&lt;p&gt;This chapter talks about communicating expectations to the users and suggests to gently exceed users' expectations in order to keep them happy using your software.&lt;/p&gt;&lt;p&gt;I must say that I agree with this book in many points except "The Extra Mile":&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;If you work closely with your users, sharing their expectations and communicating what you're doing, then there will be few surprises when the project gets delivered.&lt;/p&gt;&lt;p&gt;This is a BAD THING. Try to surprise your users. Not scare them, mind you, but &lt;i&gt;delight&lt;/i&gt; them.&lt;/p&gt;&lt;/blockquote&gt;&lt;p&gt;Did I miss something here? I understand that a good surprise may pay off, but who knows? It may not be so good after all. Only customers will tell if the "surprise feature" is good.&lt;/p&gt;&lt;p&gt;Maybe I'm too pragmatic (more pragmatic than the pragmatic programmer), but I would feel better to have a happy customer with less surprises. However, the marketing guys may have a different opinion...&lt;/p&gt;&lt;p&gt;What is your opinion? Do you give your users little surprises to delight them? If so, I'd like to hear from you.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-7710926738624321840?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/7710926738624321840/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=7710926738624321840' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/7710926738624321840'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/7710926738624321840'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/03/managing-user-expectations.html' title='Managing User Expectations'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-7044112917356641822</id><published>2007-03-19T20:08:00.000+11:00</published><updated>2008-12-10T17:13:54.055+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='unit testing'/><category scheme='http://www.blogger.com/atom/ns#' term='iteration'/><category scheme='http://www.blogger.com/atom/ns#' term='xp'/><category scheme='http://www.blogger.com/atom/ns#' term='planning'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='evolution'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>Refactoring or Redesign?</title><content type='html'>&lt;p&gt;If you ever worked on a software that has grown organically over time, you will agree that many candidates for &lt;a href="http://www.refactoring.com/"&gt;refactoring&lt;/a&gt; can be found in it. These are identified as pain points, smells or simply things that suck. The reason is that as the software grows, requirements change and code needs to adapt in order to support these changes.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.atlassian.com/software/jira/"&gt;JIRA&lt;/a&gt; is not an exception. JIRA team will spend around 30 hours in each eight week release cycle on refactoring of existing code, improving design, making it easier to extend the current code base with new features. At the &lt;a href="http://www.martinfowler.com/articles/planningXpIteration.html#IDANE5AC"&gt;iteration planning meeting&lt;/a&gt; last week, my colleagues and I were discussing how to spend this time in the most efficient way, debating what is refactoring and what is not. One of my colleagues raised a question: "Is is refactoring or redesign?"&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_PDUXIgOmBNo/Rf5Vv8oGoNI/AAAAAAAAABU/yfp5P9YPnFU/s1600-h/pp_cover_small.jpg"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://2.bp.blogspot.com/_PDUXIgOmBNo/Rf5Vv8oGoNI/AAAAAAAAABU/yfp5P9YPnFU/s200/pp_cover_small.jpg" alt="" id="BLOGGER_PHOTO_ID_5043562914918080722" border="0" /&gt;&lt;/a&gt;The answer is: "It's both."&lt;/p&gt;&lt;p&gt;According to &lt;a href="http://www.pragmaticprogrammer.com/ppbook/index.shtml"&gt;The Pragmatic Programmer: From Journeyman to Master&lt;/a&gt; written by Andrew Hunt and David Thomas:&lt;/p&gt;&lt;blockquote&gt;&lt;p&gt;At its heart, refactoring is redesign. Anything that you or others on your team designed can be redesigned in light of new facts, deeper understandings, changing requirements, and so on. But if you proceed to rip up vast quantities of code with wild abandon, you may find yourself in a worse position that when you started.&lt;/p&gt;&lt;p&gt;Clearly, refactoring is an activity that needs to be undertaken slowly, deliberately, and carefully. &lt;a href="http://martinfowler.com/"&gt;Martin Fowler&lt;/a&gt; offers the following simple tips on how to refactor without doing more harm than good:&lt;/p&gt;&lt;p&gt;&lt;ol&gt;&lt;li&gt;Don't try to refactor and add functionality at the same time.&lt;/li&gt;&lt;li&gt;Make sure you have good tests before you begin refactoring. Run the tests as often as possible. That way you will know quickly if your changes have broken anything.&lt;/li&gt;&lt;li&gt;Take short, deliberate steps: move a field from one class to another, fuse two similar methods into a superclass. Refactoring often involves making many localized changes that result in a larger-scale change. If you keep your steps small, and test after each step, you will avoid prolonged debugging.&lt;/li&gt;&lt;/ol&gt;&lt;/blockquote&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-7044112917356641822?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/7044112917356641822/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=7044112917356641822' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/7044112917356641822'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/7044112917356641822'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/03/refactoring-or-redesign.html' title='Refactoring or Redesign?'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_PDUXIgOmBNo/Rf5Vv8oGoNI/AAAAAAAAABU/yfp5P9YPnFU/s72-c/pp_cover_small.jpg' height='72' width='72'/><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-4699034353140505817</id><published>2007-02-27T19:47:00.000+11:00</published><updated>2008-12-10T17:13:54.807+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='boolean'/><category scheme='http://www.blogger.com/atom/ns#' term='string'/><category scheme='http://www.blogger.com/atom/ns#' term='best practice'/><title type='text'>toString() and primitive values</title><content type='html'>&lt;h3&gt;&lt;a href="http://www.flickr.com/photos/nicklawes/185099129/"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://1.bp.blogspot.com/_PDUXIgOmBNo/RePz9NNfSvI/AAAAAAAAAAw/VPmHmh-2fIA/s200/185099129_2487c835ca_t.jpg" alt="" id="BLOGGER_PHOTO_ID_5036137041174153970" border="0" /&gt;&lt;/a&gt;How can one convert a primitive value such as integer or boolean to String object?&lt;/h3&gt;&lt;p&gt;Well, there are many ways. There is one way that I have seen so many times:&lt;/p&gt;&lt;p style="font-family: Courier New; color: blue;"&gt;String strValue = new Integer(intValue).toString();&lt;/p&gt;&lt;p&gt;or&lt;/p&gt;&lt;p style="font-family: Courier New; color: blue;"&gt;String strValue = new Boolean(booleanValue).toString();&lt;/p&gt;&lt;p&gt;Similarly new instance can be created and the &lt;span style="font-family:Courier New;"&gt;toString()&lt;/span&gt; method invoked on classes such as &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Integer.html"&gt;Integer&lt;/a&gt;, &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Long.html"&gt;Long&lt;/a&gt;, &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Float.html"&gt;Float&lt;/a&gt;, &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Double.html"&gt;Double&lt;/a&gt;, &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Byte.html"&gt;Byte&lt;/a&gt;, &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Short.html"&gt;Short&lt;/a&gt; and &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Boolean.html"&gt;Boolean&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The problem is that a boxed primitive is allocated just to call &lt;span style="font-family:Courier New;"&gt;toString()&lt;/span&gt; method on it. Each time this is executed, a new instance, new object is created. However, object creation is not necessary and can be avoided. Creating object just for one method call is highly inefficient as the object can be garbage collected on the consecutive line.&lt;/p&gt;&lt;h3&gt;&lt;a href="http://www.flickr.com/photos/nicklawes/185098986/in/photostream/"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://4.bp.blogspot.com/_PDUXIgOmBNo/ReP069NfSwI/AAAAAAAAAA4/1m76OwVF6uQ/s200/185098986_660e24b4fb_t.jpg" alt="" id="BLOGGER_PHOTO_ID_5036138102031076098" border="0" /&gt;&lt;/a&gt;The solution&lt;/h3&gt;&lt;p&gt;It is more efficient to use the static form of &lt;span style="font-family:Courier New;"&gt;toString()&lt;/span&gt; method, which takes the primitive value as a parameter.&lt;/p&gt;&lt;p style="font-family: Courier New; color: blue;"&gt;String strValue = Integer.toString(intValue);&lt;/p&gt;&lt;p&gt;or&lt;/p&gt;&lt;p style="font-family: Courier New; color: blue;"&gt;String strValue = Boolean.toString(booleanValue);&lt;/p&gt;&lt;h3&gt;&lt;a href="http://www.flickr.com/photos/nicklawes/185098741/in/photostream/"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://3.bp.blogspot.com/_PDUXIgOmBNo/ReP1WtNfSxI/AAAAAAAAABA/bC5eNGUoZkM/s200/185098741_12fad6b83f_t.jpg" alt="" id="BLOGGER_PHOTO_ID_5036138578772445970" border="0" /&gt;&lt;/a&gt;Side note&lt;/h3&gt;&lt;p&gt;...and please don't do the following&lt;/p&gt;&lt;p style="font-family: Courier New; color: blue;"&gt;Integer number = ...&lt;br /&gt;String strValue = Integer.toString(number.intValue());&lt;/p&gt;&lt;p&gt;If you already have an instance of integer wrapper class, simply call&lt;/p&gt;&lt;p style="font-family: Courier New; color: blue;"&gt;String strValue = number.toString();&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-4699034353140505817?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/4699034353140505817/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=4699034353140505817' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4699034353140505817'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4699034353140505817'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/02/tostring-and-primitive-values.html' title='toString() and primitive values'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_PDUXIgOmBNo/RePz9NNfSvI/AAAAAAAAAAw/VPmHmh-2fIA/s72-c/185099129_2487c835ca_t.jpg' height='72' width='72'/><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-4502324124945584755</id><published>2007-02-22T19:02:00.000+11:00</published><updated>2008-12-10T17:13:54.982+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='logging'/><category scheme='http://www.blogger.com/atom/ns#' term='planning'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>Log4J Logger vs. Category</title><content type='html'>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/judahm/298847874/"&gt;&lt;img style="margin: 4pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://3.bp.blogspot.com/_PDUXIgOmBNo/Rd1T_NNfSuI/AAAAAAAAAAk/U081Kx-30_g/s200/298847874_47df4d842f_s.jpg" alt="" id="BLOGGER_PHOTO_ID_5034272303813184226" border="0" /&gt;&lt;/a&gt;&lt;span style="font-weight: bold;"&gt;Logging&lt;/span&gt; is the practice of recording sequential data. This is also a low-tech method of debugging and in some cases also the only way as the proper debugging tools may not be always available or applicable. Logging in Java can range from simple &lt;span style="font-family:Courier New;"&gt;System.out.println()&lt;/span&gt; statements to usage of sophisticated logging frameworks.&lt;/p&gt;&lt;p&gt;At the time of writing there are several &lt;span style="font-weight: bold;"&gt;logging frameworks&lt;/span&gt; for logging in Java available. There is a popular and probably the most widely used &lt;a href="http://logging.apache.org/log4j/docs/index.html"&gt;Log4J&lt;/a&gt; framework. Younger brother of Log4J is the Java's &lt;a href="http://java.sun.com/j2se/1.4.2/docs/guide/util/logging/overview.html"&gt;Logging API&lt;/a&gt; that became part of Java SE in version 1.4. See &lt;a href="http://builder.com.com/5100-22-1046694.html"&gt;How does the Java logging API stack up against log4j&lt;/a&gt; for comparison. The are many other logging frameworks: &lt;a href="https://simple-log.dev.java.net/"&gt;SimpleLog&lt;/a&gt;, &lt;a href="http://jlo.jzonic.org/"&gt;jLo&lt;/a&gt;, &lt;a href="http://protomatter.sourceforge.net/"&gt;Protomatter Syslog&lt;/a&gt;, etc.&lt;/p&gt;&lt;p&gt;There are also several frameworks that enable abstraction from logging frameworks, also known as &lt;span style="font-weight: bold;"&gt;logging bridges&lt;/span&gt; (&lt;a href="http://jakarta.apache.org/commons/logging/"&gt;Apache Commons Logging&lt;/a&gt;, &lt;a href="https://log-bridge.dev.java.net/"&gt;log-bridge&lt;/a&gt;). These allow switching between logging frameworks. These and many others can be found at &lt;a href="http://www.java-source.net/open-source/logging"&gt;Open Source Logging Tools in Java&lt;/a&gt; at java-source.net.&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold;"&gt;Log4J&lt;/span&gt; was one of the early logging frameworks that gained popularity and is present in many source code bases. In some cases you could encounter usage of Category class rather than Logger. If you work or worked on projects that are built on top of relatively young frameworks, you may not even know that Category class exists as its natural habitat is in old Java code. I hadn't known that Category class existed until I saw it one day. I saw it in a place where I would usually use Logger class. Since that day I kept reminding myself to look at it and see what's different from Logger class and why would one use it.&lt;/p&gt;&lt;p&gt;So what is the difference between &lt;a href="http://logging.apache.org/log4j/docs/api/org/apache/log4j/Category.html" style="font-family: Courier New;"&gt;Category&lt;/a&gt; and &lt;a href="http://logging.apache.org/log4j/docs/api/org/apache/log4j/Logger.html" style="font-family: Courier New;"&gt;Logger&lt;/a&gt; classes? The Java documentation in &lt;span style="font-family:Courier New;"&gt;Category&lt;/span&gt; class states&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;This class has been deprecated and replaced by the Logger subclass. It will be kept around to preserve backward compatibility until mid 2003.&lt;br /&gt;&lt;br /&gt;Logger is a subclass of Category, i.e. it extends Category. In other words, a logger is a category. Thus, all operations that can be performed on a category can be performed on a logger. Internally, whenever log4j is asked to produce a Category object, it will instead produce a Logger object. Log4j 1.2 will never produce Category objects but only Logger instances. In order to preserve backward compatibility, methods that previously accepted category objects still continue to accept category objects.&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Then the following example shows how &lt;span style="font-family:Courier New;"&gt;Category&lt;/span&gt; was used and how &lt;span style="font-family:Courier New;"&gt;Logger&lt;/span&gt; should be used.&lt;/p&gt;&lt;p style="font-family: Courier New; color: blue;"&gt;// Deprecated form:&lt;br /&gt;Category cat = Category.getInstance("foo.bar");&lt;br /&gt;&lt;br /&gt;// Preferred form for retrieving loggers:&lt;br /&gt;Logger logger = Logger.getLogger("foo.bar");&lt;/p&gt;&lt;p&gt;And that's it. That's all you have to do to replace &lt;span style="font-family:Courier New;"&gt;Category&lt;/span&gt; with Logger (apart from renaming the variable).&lt;/p&gt;&lt;p&gt;The documentation also says&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;span style="font-weight: bold;"&gt;There is absolutely no need for new client code to use or refer to the &lt;span style="font-family:Courier New;"&gt;Category&lt;/span&gt; class.&lt;/span&gt; Whenever possible, please avoid referring to it or using it.&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Why is this important? The plan is that from Log4J version 1.3 &lt;span style="font-weight: bold;"&gt;Category class will be removed&lt;/span&gt;! What can we do to prepare our code for Log4J 1.3? Well &lt;a href="http://www.qos.ch/logging/preparingFor13.jsp"&gt;Preparing for Log4J version 1.3&lt;/a&gt; has it all spelled out. It's worth to read if you want to understand all implications this upgrade may have. I just shamelessly paste the steps here:&lt;br /&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;ol&gt;&lt;li&gt;Never refer to the &lt;code&gt;Category&lt;/code&gt; class directly, refer to &lt;code&gt;Logger&lt;/code&gt; instead.&lt;/li&gt;&lt;li&gt;Do not invoke the deprecated &lt;a href="http://logging.apache.org/log4j/docs/api-1.2.8/org/apache/log4j/Category.html#getRoot%28%29"&gt;&lt;code&gt;Category.getRoot&lt;/code&gt;&lt;/a&gt;       method. Invoke &lt;a href="http://logging.apache.org/log4j/docs/api-1.2.8/org/apache/log4j/Logger.html#getRootLogger%28%29"&gt;&lt;code&gt;Logger.getRootLogger&lt;/code&gt;&lt;/a&gt;       method instead.&lt;/li&gt;&lt;li&gt;Do not invoke the deprecated &lt;a href="http://logging.apache.org/log4j/docs/api-1.2.8/org/apache/log4j/Category.html#getInstance%28java.lang.String%29"&gt;&lt;code&gt;Category.getInstance(String)&lt;/code&gt;&lt;/a&gt;       method. Invoke &lt;a href="http://logging.apache.org/log4j/docs/api-1.2.8/org/apache/log4j/Logger.html#getLogger%28java.lang.String%29"&gt;&lt;code&gt;Logger.getLogger(String)&lt;/code&gt;&lt;/a&gt;       method instead.&lt;/li&gt;&lt;li&gt;Do not invoke the deprecated &lt;a href="http://logging.apache.org/log4j/docs/api-1.2.8/org/apache/log4j/Category.html#getInstance%28java.lang.Class%29"&gt;&lt;code&gt;Category.getInstance(Class)&lt;/code&gt;&lt;/a&gt;     method. Invoke &lt;a href="http://logging.apache.org/log4j/docs/api-1.2.8/org/apache/log4j/Logger.html#getLogger%28java.lang.Class%29"&gt;&lt;code&gt;Logger.getLogger(Class)&lt;/code&gt;&lt;/a&gt;     method instead.&lt;/li&gt;&lt;li&gt;Never refer to the &lt;code&gt;Priority&lt;/code&gt; class, refer to &lt;code&gt;Level&lt;/code&gt; class instead.&lt;/li&gt;&lt;li&gt;Do not invoke the deprecated &lt;a href="http://logging.apache.org/log4j/docs/api-1.2.8/org/apache/log4j/Category.html#setPriority%28org.apache.log4j.Priority%29"&gt;&lt;code&gt;Category.setPriority(Priority)&lt;/code&gt;&lt;/a&gt;       method. Invoke &lt;a href="http://logging.apache.org/log4j/docs/api-1.2.8/org/apache/log4j/Category.html#setLevel%28org.apache.log4j.Level%29"&gt;&lt;code&gt;Logger.setLevel(Level)&lt;/code&gt;&lt;/a&gt;       method instead.&lt;/li&gt;&lt;li&gt;Do not invoke the deprecated &lt;a href="http://logging.apache.org/log4j/docs/api-1.2.8/org/apache/log4j/Priority.html#toPriority%28int%29"&gt;&lt;code&gt;Priority.toPriority(int)&lt;/code&gt;&lt;/a&gt;       method. Invoke &lt;a href="http://logging.apache.org/log4j/docs/api-1.2.8/org/apache/log4j/Level.html#toLevel%28int%29"&gt;&lt;code&gt;Level.toLevel(int)&lt;/code&gt;&lt;/a&gt;       method instead. The same holds true for the other variants of the &lt;code&gt;Priority.toPriority&lt;/code&gt; method.&lt;/li&gt;&lt;li&gt;Never refer to the deprecated &lt;code&gt;Priority.FATAL&lt;/code&gt;, &lt;code&gt;Priority.ERROR&lt;/code&gt;, &lt;code&gt;Priority.WARN&lt;/code&gt;, &lt;code&gt;Priority.INFO&lt;/code&gt;, &lt;code&gt;Priority.DEBUG&lt;/code&gt; fields. Refer to the &lt;code&gt;Level.FATAL&lt;/code&gt;, &lt;code&gt;Level.ERROR&lt;/code&gt;, &lt;code&gt;Level.WARN&lt;/code&gt;, &lt;code&gt;Level.INFO&lt;/code&gt;, &lt;code&gt;Level.DEBUG&lt;/code&gt; fields instead.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;If you confiugure appenders programmatically, do not forget to invoke the &lt;code&gt;activateOptions&lt;/code&gt; method of an appender after you have instantiated it and set its options.&lt;/li&gt;&lt;/ol&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;and as the above mentioned document says&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;For 99.99% of users, this translates to the following string find-and-replace operations:&lt;ol&gt;&lt;li&gt;Replace the string "Category.getInstance" with the string "Logger.getLogger".&lt;/li&gt;&lt;li&gt;Replace the string "Category.getRoot" with the string "Logger.getRootLogger".&lt;/li&gt;&lt;li&gt;Replace the string "Category" with the string "Logger".&lt;/li&gt;&lt;li&gt;Replace the string "Priority" with the string "Level".   &lt;/li&gt;&lt;/ol&gt; &lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Happy logging!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-4502324124945584755?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/4502324124945584755/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=4502324124945584755' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4502324124945584755'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4502324124945584755'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/02/log4j-logger-vs-category.html' title='Log4J Logger vs. Category'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://3.bp.blogspot.com/_PDUXIgOmBNo/Rd1T_NNfSuI/AAAAAAAAAAk/U081Kx-30_g/s72-c/298847874_47df4d842f_s.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-3734308817920332711</id><published>2007-02-06T13:35:00.000+11:00</published><updated>2007-04-15T21:01:59.022+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='uml'/><category scheme='http://www.blogger.com/atom/ns#' term='installation'/><category scheme='http://www.blogger.com/atom/ns#' term='vista'/><category scheme='http://www.blogger.com/atom/ns#' term='windows'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>To Vista or Not To Vista?</title><content type='html'>&lt;p&gt;Sysadmin in our company posted a message regarding Vista installations. I found it very funny and quote him here with his permission:&lt;/p&gt;&lt;p&gt;&lt;blockquote&gt;On a related note now that Vista has been officially released, and inspired by some &lt;a href="http://www.bbspot.com/News/2007/02/windows-vista-upgrade-decision-flowchart.html"&gt;helpful pages&lt;/a&gt; that others have produced I thought I'd preempt the inevitable requests for installation and come up with the following decision-tree to see if you qualify for an upgrade:&lt;/p&gt;&lt;p&gt;&lt;img src="http://farm1.static.flickr.com/187/380277781_4b313b3f7e.jpg?v=0" alt="Vista Installation Decision Tree" /&gt;&lt;/blockquote&gt;&lt;/p&gt;&lt;p&gt;It's all crystal clear now :-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-3734308817920332711?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/3734308817920332711/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=3734308817920332711' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/3734308817920332711'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/3734308817920332711'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/02/to-vista-or-not-to-vista.html' title='To Vista or Not To Vista?'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-2233663667460976031</id><published>2007-02-04T21:31:00.000+11:00</published><updated>2008-12-10T17:13:55.296+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='array'/><category scheme='http://www.blogger.com/atom/ns#' term='element'/><title type='text'>Trailing Comma in Arrays</title><content type='html'>&lt;p&gt;&lt;a href="http://www.flickr.com/photos/abq/111979653/"&gt;&lt;img style="margin: 0pt 10pt 10px 0px; float: right; cursor: pointer;" src="http://1.bp.blogspot.com/_PDUXIgOmBNo/RcXAsWLoJrI/AAAAAAAAAAY/R6TUe4Phvy4/s320/111979653_8a6edc6f7e_t.jpg" alt="" id="BLOGGER_PHOTO_ID_5027636427130152626" border="0" /&gt;&lt;/a&gt; Most of us know how to initialize arrays. A usual way to initialize array is to specify all its elements. For example an array of integers can be initialized in following way:&lt;/p&gt;&lt;pre style="color: blue;"&gt;Integer[] integerArray = new Integer[] {&lt;br /&gt;    new Integer(1),&lt;br /&gt;    new Integer(2),&lt;br /&gt;    new Integer(4)&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;I was generating code for a unit test and needed to create a List that I would pass to the constructor of a particular class I wanted to test. So I took the easiest  way to create array then convert it to the list. In the process I generated the elements of the array by copying and pasting previously added element. The code looked like this:&lt;/p&gt;&lt;code&gt;&lt;/code&gt;&lt;pre style="color: blue;"&gt;List initList = Arrays.asList(new Integer[] {&lt;br /&gt;    new Integer(1),&lt;br /&gt;    new Integer(2),&lt;br /&gt;    new Integer(1),&lt;br /&gt;    new Integer(2),&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;Notice the trailing comma! To my surprise, my IDE did not warn me about compilation error, moreover the code compiled and ran just fine.&lt;/p&gt;&lt;p&gt;According to Java Language Specification, chapter &lt;a href="http://java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html#11358"&gt;10.6 Array Initializers&lt;/a&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;An array initializer is written as a comma-separated list of expressions, enclosed by braces "{" and "}".&lt;br /&gt;&lt;br /&gt;The length of the constructed array will equal the number of expressions.&lt;br /&gt;&lt;br /&gt;The expressions in an array initializer are executed from left to right in the textual order they occur in the source code. The nth variable initializer specifies the value of the n-1st array component. Each expression must be assignment-compatible (§5.2) with the array's component type, or a compile-time error results.&lt;br /&gt;&lt;br /&gt;If the component type is itself an array type, then the expression specifying a component may itself be an array initializer; that is, array initializers may be nested.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;A trailing comma may appear after the last expression in an array initializer and is ignored.&lt;/span&gt;&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;I must admit that I never used trailing commas in arrays in my whole software engineering career and on this occasion, this took my be surprise. I guess making mistakes it one way of discovering the truth and realizing that a mistake may not be a mistake after all.&lt;/p&gt;&lt;p&gt;So, there you go! Initializing arrays in Java with a trailing comma is totally valid. I learn something new every day :-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-2233663667460976031?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/2233663667460976031/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=2233663667460976031' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/2233663667460976031'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/2233663667460976031'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/02/trailing-comma-in-arrays.html' title='Trailing Comma in Arrays'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_PDUXIgOmBNo/RcXAsWLoJrI/AAAAAAAAAAY/R6TUe4Phvy4/s72-c/111979653_8a6edc6f7e_t.jpg' height='72' width='72'/><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-1297847645440839119</id><published>2007-01-30T21:43:00.000+11:00</published><updated>2007-02-09T12:19:59.228+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>Method Invocation vs. Local Store</title><content type='html'>&lt;p&gt;On many occasions, I have seen the code that invokes the same method on the same object several times within few consecutive lines of code. Let's have a look at the following code snippet:&lt;/p&gt;&lt;pre style="color: rgb(0, 0, 153);"&gt;if(person.getDateOfBirth() != null) {&lt;br /&gt;  System.out.println("Date of birth: " + person.getDateOfBirth());&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;When I see this repetition of code I feel like I should refactor it order to remove the duplicity. Refactoring itself would be very easy. The return value would be stored in a local variable and used wherever the original method was invoked.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;The example above could be refactored in following way:&lt;/p&gt;&lt;pre style="color: rgb(0, 0, 153);"&gt;&lt;span style="color: rgb(0, 153, 0);"&gt;final Date dob =person.getDateOfBirth();&lt;/span&gt;&lt;br /&gt;if (&lt;span style="color: rgb(0, 153, 0);"&gt;dob&lt;/span&gt; != null) {&lt;br /&gt;  System.out.println("Date of birth: " + &lt;span style="color: rgb(0, 153, 0);"&gt;dob&lt;/span&gt;);&lt;br /&gt;}&lt;/pre&gt;&lt;p&gt;The reason behind my urge to refactor such code is in performance. Method invocation can repeatedly cause execution of potentially expensive operations such as slow database access, network communication or some lengthly calculations.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;If in the example above the date of birth of &lt;code&gt;person&lt;/code&gt; object was very unlikely to change between the two &lt;code&gt;getDateOfBirth()&lt;/code&gt; method invocations and therefore it was a safe bet to store the result locally in a local variable.&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold;"&gt;Invoking a method once, storing the result in a local variable could speed the application up. However, it could also break it.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Why would a local store break the application? Well, it may not, it really depends on the invoked method itself and the way our application uses the returned value. If a method performs some side operations it actually may rely on its invocation. Such operations can be for example increasing a counter, retrieving updated stock ticker info, etc. The return value may also depend on the number or time of invocations or other things that may affect it. Another example would be an application that performs business logic based on the most recent data.If the data that method returns varies frequently and business logic depends on it, storing it may not be such a good idea.&lt;/p&gt;&lt;p&gt;I'll give you a very bad example here, but this is the extreme where the result is guaranteed to return a different result almost every time:&lt;/p&gt;&lt;pre style="color: rgb(0, 0, 153);"&gt;if (Math.random() &lt; 0.5) {&lt;br /&gt;  // notify developer A&lt;br /&gt;} else if(Math.random() &gt;= 0.5) {&lt;br /&gt;  // notify developer B&lt;br /&gt;} else {&lt;br /&gt;  // this should never happen,right?&lt;br /&gt;  // :-)&lt;br /&gt;  // but it does happen with likelihood of 25%&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;So it really brings us down to the point where we have to examine &lt;strong&gt;what the method does&lt;/strong&gt;, &lt;strong&gt;what data it returns&lt;/strong&gt; and &lt;strong&gt;what the client does with the returned data&lt;/strong&gt;.&lt;/p&gt;&lt;h3&gt;Conclusion&lt;br /&gt;&lt;/h3&gt;&lt;ul&gt;&lt;li&gt;Use &lt;span style="font-weight: bold;"&gt;local store&lt;/span&gt; if the invoked method returns consistent results and has no side-effects. Method invocation could be slower or potentially break the client code.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Use &lt;span style="font-weight: bold;"&gt;method invocation&lt;/span&gt; if the method    invoked has side-effects or the data returned changes frequently and the client relies on the latest result.&lt;/li&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-1297847645440839119?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/1297847645440839119/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=1297847645440839119' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1297847645440839119'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1297847645440839119'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2007/01/method-invocation-vs.html' title='Method Invocation vs. Local Store'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-8997714314746788846</id><published>2006-12-17T15:30:00.000+11:00</published><updated>2006-12-17T15:58:22.411+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='iteration'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='best practice'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>Recursion vs. Loop</title><content type='html'>&lt;h3&gt;Problem&lt;/h3&gt;&lt;p&gt;Imagine that your application is meant to process an XML file. It is given a tag and needs to find a "special tag" that this tag might be nested in. This problem has several solutions. I tackled a similar problem some time ago and I will present you with some of the solutions that I considered.&lt;/p&gt;&lt;h3&gt;While loop&lt;/h3&gt;&lt;pre&gt;&lt;code style="color: Blue;"&gt;private SpecialTag findSpecialTag()&lt;br /&gt;{&lt;br /&gt;  Tag parent = this.getParentTag();&lt;br /&gt;  while (parent != null &amp;amp;&amp;amp; !(parent instanceof SpecialTag))&lt;br /&gt;  {&lt;br /&gt;    parent = parent.getParentTag();&lt;br /&gt;  }&lt;br /&gt;  return (SpecialTag) parent;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Do-while loop&lt;/h3&gt;&lt;pre&gt;&lt;code style="color: Blue;"&gt;private SpecialTag findSpecialTag()&lt;br /&gt;{&lt;br /&gt;  Tag parent = this;&lt;br /&gt;  do&lt;br /&gt;  {&lt;br /&gt;    parent = parent.getParentTag();&lt;br /&gt;  }&lt;br /&gt;  while (parent != null &amp;amp;&amp;amp; !(parent instanceof SpecialTag));&lt;br /&gt;  return (SpecialTag) parent;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Recursion&lt;/h3&gt;&lt;pre&gt;&lt;code style="color: Blue;"&gt;private SpecialTag findSpecialTag()&lt;br /&gt;{&lt;br /&gt;  return findSpecialTag(this.getParentTag());&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;private SpecialTag findSpecialTag(Tag tag)&lt;br /&gt;{&lt;br /&gt;  if (tag == null || tag instanceof SpecialTag)&lt;br /&gt;  {&lt;br /&gt;    return (SpecialTag) tag;&lt;br /&gt;  }&lt;br /&gt;  else&lt;br /&gt;  {&lt;br /&gt;    return findSpecialTag(tag.getParentTag());&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;h3&gt;Solution&lt;/h3&gt;&lt;p&gt;In my personal opinion, I find the while loop cleanest and simplest to understand. Do-while loop gets a bit messy with the condition at the end and recursion is probably the worst. I find recursion a bit hard to follow. It can also introduce an extra method just for its own sake (as in this example).&lt;/p&gt;&lt;p&gt;I do not have a strong opinion on this topic. If you like to program recursions, while loops, do-while loops, or for loops, it's fine by me. I certainly will not change your code, but if you ask me to write some code, it'd most likely be a while (or for) loop.&lt;/p&gt;&lt;p&gt;I use while and for loops interchangeably. The previous example with while loop would look like this with for loop:&lt;/p&gt;&lt;pre&gt;&lt;code style="color: Blue;"&gt;private SpecialTag findSpecialTag()&lt;br /&gt;{&lt;br /&gt;  Tag p = this.getParentTag();&lt;br /&gt;  for(; p != null &amp;amp;&amp;amp; !(p instanceof SpecialTag); p = p.getParentTag());&lt;br /&gt;  return (SpecialTag) parent;&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;What is your preference?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-8997714314746788846?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/8997714314746788846/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=8997714314746788846' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/8997714314746788846'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/8997714314746788846'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/12/recursion-vs-loop.html' title='Recursion vs. Loop'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-7155933510756023318</id><published>2006-12-17T13:29:00.000+11:00</published><updated>2007-04-15T21:12:23.520+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pair programming'/><category scheme='http://www.blogger.com/atom/ns#' term='xp'/><title type='text'>Big Screen</title><content type='html'>&lt;p&gt;&lt;a href="http://martinfowler.com/"&gt;Martin Fowler&lt;/a&gt; in his recent blog post about &lt;a href="http://martinfowler.com/bliki/BigScreen.html"&gt;big screen&lt;/a&gt; emphasizes the importance of the workspace size, as in the size of the screen. He says that you cannot see much on a small screen and must switch between windows that overlap each other. I totally agree with him.&lt;/p&gt;&lt;p&gt;I was lucky enough to work at companies that could afford spending a little extra for the benefit of increased productivity. At &lt;a href="http://www.siemens.com/sbs/"&gt;Siemens&lt;/a&gt; I had 21" monitor, which was the biggest you could get at that time. Then at &lt;a href="http://www.3d3.com/"&gt;3D3.com&lt;/a&gt;, I had two 17" monitors, which was again an excellent choice (one screen for programming, second screen for running the app/testing).&lt;/p&gt;&lt;p&gt;Fast forward to present, I work at &lt;a href="http://www.atlassian.com/"&gt;Atlassian&lt;/a&gt; and the choices are great. If you work fulltime you can choose between a huge 24" widescreen monitor or TWO 20" widescreen monitors. When I got my 24" monitor, the &lt;a href="http://hanuska.blogspot.com/2006/06/pair-programming-just-got-better.html"&gt;pair programming just got better&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;I use a laptop at home and I used laptops for work at &lt;a href="http://www.mercurysolutions.biz/"&gt;MSC&lt;/a&gt; and &lt;a href="http://www.agreon.com/"&gt;Agreon&lt;/a&gt;. I never had any problems with my eyesight. Except the time when I worked for Agreon and used a Dell laptop. My eyesight got worse and I had to wear glasses at the end of the day as my eyes were strained. Now at Atlassian, with 24" monitor in front of me, I don't need to use my glasses any more. My vision is just fine. &lt;span style="font-style: italic;"&gt;(It must've been the screen of that Dell laptop, IBMs and Toshibas are fine)&lt;/span&gt; If you use a laptop, at least ask for a stand so you raise the screen to your eye height. A simple bookstand will do as long as it is strong enough. Anyway, &lt;a href="http://hanuska.blogspot.com/2006/06/why-laptops-are-no-good-for-pair.html"&gt;laptops are no good for pair programming&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;So a big screen is good as you can display more valuable information on the screen. However, one screen still does not save you from application switching. If you are lucky enough to have two screens, you know what I am talking about. It's just a pleasure not to be forced to switch between apps as you can easily have one on one screen and the other on the second screen. A typical scenario is coding and running the (web) application, or coding and reading documentation.&lt;/p&gt;&lt;p&gt;At Atlassian we take turns in support. A developer from each team takes a fortnight turn to join the support team. We usually move to support area (so we can be close to the members of support team). We have a dedicated "support desk", which has all hardware necessary. The only piece missing is the computer that the developer brings along. The monitor on support desk is a 24" widescreen monitor.&lt;/p&gt;&lt;p&gt;When people move to support they bring their own desktop computers. I drag my monitor as well. It's the same 24" monitor and I always think that it'd be a waste to let it sit unused on my "dev" desk for two weeks. I hook it up and voilá! Two 24" widescreen monitors give me the greatest work space I can get (for now). I gotta tell you, it's really fantastic to have these two screens. You can be digging in the code on one screen and doing something else on the other screen. I usually have a virtual machine running on one and a browser in the other. No switching, no overlapping windows.&lt;/p&gt;&lt;p&gt;If you want to see me in action with two 24" monitors, have a look at these videos about Atlassian and my bosses Scott and Mike [&lt;a href="http://abc.net.au/reslib/podcast/latelinebusiness/20061130-latebiz-atlassian_video4.m4v"&gt;mp4&lt;/a&gt;] or [&lt;a href="http://abc.net.au/reslib/podcast/latelinebusiness/20061130-latebiz-atlassian_video4.wmv"&gt;wmv&lt;/a&gt;] (around 1 min 40 sec).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-7155933510756023318?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/7155933510756023318/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=7155933510756023318' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/7155933510756023318'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/7155933510756023318'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/12/big-screen.html' title='Big Screen'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-8829748374573343223</id><published>2006-12-11T21:57:00.000+11:00</published><updated>2008-12-10T17:13:55.442+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='deployment'/><category scheme='http://www.blogger.com/atom/ns#' term='build'/><category scheme='http://www.blogger.com/atom/ns#' term='installation'/><category scheme='http://www.blogger.com/atom/ns#' term='automation'/><category scheme='http://www.blogger.com/atom/ns#' term='project'/><title type='text'>Project Automation</title><content type='html'>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://www.amazon.com/gp/product//0974514039/"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://4.bp.blogspot.com/_PDUXIgOmBNo/RX0_GMlYjwI/AAAAAAAAAAM/EzixBgi7P_o/s320/ppa.jpg" alt="" id="BLOGGER_PHOTO_ID_5007227736395648770" border="0" /&gt;&lt;/a&gt;I just finished reading &lt;a href="http://www.amazon.com/gp/product//0974514039/"&gt;&lt;span style="font-weight: bold;"&gt;Pragmatic Project Automation&lt;/span&gt;&lt;/a&gt; (How to Build, Deploy and Monitor Java Applications) written by Mike Clark.&lt;/p&gt;&lt;p&gt;This book is very well written and an easy read. I picked it from the shelf in our &lt;a href="http://www.atlassian.com/"&gt;Atlassian&lt;/a&gt; library two months ago. I read it mostly in the mornings and evenings on the train commuting to the office. I must say that even my trips take only 20 minutes, in those 20 minutes I managed to read just enough to get me started thinking about software processes that we have in place and how to improve them.&lt;/p&gt;&lt;p&gt;There were many things in the book that I was quite familiar with. I have already used &lt;a href="http://ant.apache.org/"&gt;Ant&lt;/a&gt;, written &lt;a href="http://www.junit.org/"&gt;unit tests&lt;/a&gt;, created scripts that build new releases. Although I was familiar with many of these aspects of project automation, there were new ideas, other angles of application of the automated processes I've never thought about. I was quite interested in reading the chapters dedicated to installation, deployment and monitoring. I have faced the dilemmas of these stages of software development and I was quite curious to find out how the author solved them.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;This book is truly inspirational. In a sense it is a cook book for project automation. It's easy to follow and proves useful to a novice as well as experienced developer.&lt;/p&gt;&lt;p&gt;I will put this book back on the shelf in our office. It's worth sharing and I will highly recommend reading it to anybody who wants to automate almost anything in software development.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-8829748374573343223?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/8829748374573343223/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=8829748374573343223' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/8829748374573343223'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/8829748374573343223'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/12/project-automation.html' title='Project Automation'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_PDUXIgOmBNo/RX0_GMlYjwI/AAAAAAAAAAM/EzixBgi7P_o/s72-c/ppa.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-8277800972522441042</id><published>2006-11-29T18:27:00.000+11:00</published><updated>2006-11-29T18:41:07.977+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ide'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>Don't hurt my files!</title><content type='html'>&lt;p&gt;I have been using &lt;a href="http://www.jetbrains.com/"&gt;IntelliJ&lt;/a&gt; &lt;a href="http://www.jetbrains.com/idea/"&gt;IDEA&lt;/a&gt; since I started working on &lt;a href="http://www.atlassian.com/software/jira/"&gt;JIRA&lt;/a&gt; at &lt;a href="http://www.atlassian.com/"&gt;Atlassian&lt;/a&gt;. I finally upgraded to IDEA 6.0.2 last week. The first impressions are good.&lt;/p&gt;&lt;p&gt;I was re-arranging the dependencies of projects and libraries and needed to remove one. What made me feel really good was this pop-up:&lt;/p&gt;&lt;p&gt;&lt;img src="http://static.flickr.com/121/308438802_3ef4e05108.jpg?v=0" /&gt;&lt;/p&gt;&lt;p&gt;I am so happy with IDEA's pacifist approach to my files. I am against the violence on the files!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-8277800972522441042?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/8277800972522441042/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=8277800972522441042' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/8277800972522441042'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/8277800972522441042'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/11/dont-hurt-my-files.html' title='Don&apos;t hurt my files!'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-1226299706429404653</id><published>2006-11-28T17:45:00.000+11:00</published><updated>2006-11-28T18:26:03.494+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>What I did not know about favicon</title><content type='html'>&lt;p&gt;Long time ago I learnt about that little file that can make your website special. I'm talking about &lt;span style="font-weight: bold;"&gt;favicon&lt;/span&gt; or favorites icon. This icon file is used when a page is bookmarked in IE5+ and Firefox.&lt;/p&gt;&lt;p&gt;I knew that this file had to be located in the root of the web server. And that was good enough for me at that time. Until today I did not know that the location of favicon.ico file did not have to be the root directory only.&lt;/p&gt;&lt;p&gt;Favicon can be associated with a webpage, not only a website. That means two things:&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;favicon placed in the root directory of the webserver is used with all web pages, no coding is necessary;&lt;/li&gt;&lt;li&gt;favicon can be placed anywhere on the webserver and must be referenced from the page in order to be used, favicon is then referred to as &lt;span style="font-weight: bold;"&gt;page icon&lt;/span&gt;.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;All you need to do to customize the page icon is to put the following line into the header section of your page:&lt;/p&gt;&lt;p&gt;&lt;code&gt;&amp;lt;link rel="shortcut icon" href="/images/favicon.ico" type="image/x-icon"&amp;gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;where the value in href points to the location of the favicon you want to associate with this page.&lt;/p&gt;&lt;p&gt;Few facts about favicon:&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;ICO file can contain multiple resolutions (the most commonly used being 16×16 and 32×32, with 64×64 and 128×128 sometimes used by Mac) and bit-depths (most common being 4, 8, 24 bpp—i.e. 16, 256 and 16 million colors) in the file;&lt;/li&gt;&lt;li&gt;image can be also any image format supported by web browser; e.g. GIF, PNG;&lt;/li&gt;&lt;li&gt;&lt;a href="http://favicon.com/"&gt;favicon.com&lt;/a&gt; is a website dedicated to favicon, it also includes an online editor.&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;So the good news is that literally every page on your website can have its own icon (which would be a nonsense, but makes a total sense for web applications running on the same server).&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-1226299706429404653?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/1226299706429404653/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=1226299706429404653' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1226299706429404653'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1226299706429404653'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/11/what-i-did-not-know-about-favicon.html' title='What I did not know about favicon'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-2434333663092300003</id><published>2006-11-27T20:43:00.000+11:00</published><updated>2006-11-27T20:49:20.458+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='evolution'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Animated CSS Evolution</title><content type='html'>&lt;p&gt;I found this quite impressive animated GIF that show an evolution of a CSS for a website. The &lt;a href="http://ajaxian.com/archives/css-evolution"&gt;original post&lt;/a&gt; with animation was created by Dion Almaer.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;img src="http://mboffin.com/stuff/designline-openair.gif" /&gt;&lt;/p&gt;&lt;p&gt;Well done!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-2434333663092300003?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/2434333663092300003/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=2434333663092300003' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/2434333663092300003'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/2434333663092300003'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/11/animated-css-evolution.html' title='Animated CSS Evolution'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-214116305868239682</id><published>2006-10-22T16:32:00.001+10:00</published><updated>2006-10-22T23:14:50.914+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='sydney'/><category scheme='http://www.blogger.com/atom/ns#' term='bike'/><category scheme='http://www.blogger.com/atom/ns#' term='cycle'/><title type='text'>70km and still kicking</title><content type='html'>&lt;p&gt;Today I took part in &lt;a href="http://www.springcycle.com.au/"&gt;Sydney Spring Cycle&lt;/a&gt; organized by &lt;a href="http://www.bicyclensw.org.au/"&gt;Bicycle NSW&lt;/a&gt;. Sydney Spring Cycle is an annual event. It takes about 50km from start in North Sydney to finish at Sydney Olympic Park in Homebush.&lt;/p&gt;&lt;p&gt;It was my first SSC ride and it was a very pleasant ride indeed. My friends and I aimed for an early start at 7am. This meant I had to get up at 5am to get ready an be in North Sydney on time. The weather was cold and it rained a bit. We warmed up quite quickly though.&lt;/p&gt;&lt;p&gt;Later during the day the sky cleared and it was a beautiful day to ride. I really enjoyed a company of thousands other rides. I rode my old mountain bike and my friends were on road bikes. To my surprise I managed quite well. I was able to keep up with them (I think they just spared me).&lt;/p&gt;&lt;p&gt;50km seemed like a lot. I usually ride 10km to work in Sydney CBD, which takes me half an hour. When we reached the 40km milestone, there was a sign "10km to go." By that time it seemed like nothing.&lt;/p&gt;&lt;p&gt;In fact, we had enough energy for a short sprint to the finish line. It was a great day out. I felt so energized that I also rode home from Homebush, adding few extra kilometers to the count.&lt;/p&gt;&lt;p&gt;At the end &lt;span style="font-weight: bold;"&gt;I did 70km&lt;/span&gt;. Here is the proof.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.flickr.com/photos/hanuska/275922848/" title="Photo Sharing"&gt;&lt;img src="http://static.flickr.com/107/275922848_adaa262885_m.jpg" alt="Sydney Spring Cycle 2006" height="240" width="240" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;I created a Sydney Spring Cycle bicycle path on &lt;a href="http://www.bikely.com/maps/bike-path/Sydney-Spring-Cycle"&gt;Bikely&lt;/a&gt;, if you are interested and would like to see it on Google map. The photos I took today can be found at &lt;a href="http://www.flickr.com/photos/hanuska/sets/72157594339166377/"&gt;Flickr&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;Thank you all who organized such a great event! I'll be there next year too!&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-214116305868239682?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/214116305868239682/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=214116305868239682' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/214116305868239682'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/214116305868239682'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/10/70km-and-still-kicking.html' title='70km and still kicking'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-30683480996257122</id><published>2006-10-05T22:54:00.000+10:00</published><updated>2006-10-05T23:29:22.703+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='microformats'/><category scheme='http://www.blogger.com/atom/ns#' term='wd06'/><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><title type='text'>Microformats - hCard</title><content type='html'>&lt;p&gt;What is new on my blog today? I added my contact information into the template. Since I learnt more about &lt;a href="http://microformats.org/"&gt;microformats&lt;/a&gt; at the &lt;a href="http://www.webdirections.org/"&gt;Web Directions&lt;/a&gt; conference, I used &lt;a href="http://microformats.org/wiki/hcard"&gt;hCard&lt;/a&gt; microformat. No, you cannot see it as the style on that &lt;code&gt;DIV&lt;/code&gt; is set to &lt;code&gt;display: none&lt;/code&gt; and that means it's there but not visible.&lt;/p&gt;&lt;p&gt;If you have &lt;a href="http://codeeg.com/tails/"&gt;Tails&lt;/a&gt; or &lt;a href="https://addons.mozilla.org/firefox/2240/"&gt;Tails Export&lt;/a&gt; extensions for &lt;a href="http://www.mozilla.com/firefox/"&gt;Firefox&lt;/a&gt; or &lt;a href="http://www.flock.com/"&gt;Flock&lt;/a&gt; browsers, you should be able to see these normally grey icons &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger2/2956/2922/1600/mf-no.png"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger2/2956/2922/200/mf-no.png" alt="" border="0" /&gt;&lt;/a&gt; get some colors &lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger2/2956/2922/1600/mf-yes.png"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger2/2956/2922/200/mf-yes.png" alt="" border="0" /&gt;&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;When you click on Tails you get&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger2/2956/2922/1600/contact.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer;" src="http://photos1.blogger.com/blogger2/2956/2922/320/contact.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;When you click on Tails Export you get&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger2/2956/2922/1600/contact-exp.png"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger2/2956/2922/320/contact-exp.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;All I added was this:&lt;/p&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;div class="vcard" style="display: none;"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;a class="url fn" href="http://hanuska.blogspot.com/"&amp;gt;Dushan Hanuska&amp;lt;/a&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;div class="adr"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;span class="locality"&amp;gt;Sydney&amp;lt;/span&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;span class="region"&amp;gt;NSW&amp;lt;/span&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;span class="postal-code"&amp;gt;2000&amp;lt;/span&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;span class="country-name"&amp;gt;Australia&amp;lt;/span&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;/div&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;span class="geo"&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;span class="latitude"&amp;gt;-33.879176&amp;lt;/span&amp;gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;lt;span class="longitude"&amp;gt;151.212044&amp;lt;/span&amp;gt;&lt;br /&gt;&amp;nbsp;&amp;lt;/span&amp;gt;&lt;br /&gt;&amp;lt;/div&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;If you want to add your hCard onto your page, you can create one using &lt;a href="http://microformats.org/code/hcard/creator"&gt;hCard Creator&lt;/a&gt;. It's quite simple and gives only the basic options, but it's a good place to start.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-30683480996257122?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/30683480996257122/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=30683480996257122' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/30683480996257122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/30683480996257122'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/10/microformats-hcard.html' title='Microformats - hCard'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-6593536148193605005</id><published>2006-10-02T20:15:00.000+10:00</published><updated>2006-10-02T20:18:19.754+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wd06'/><title type='text'>Cool Links from Web Directions South 2006</title><content type='html'>&lt;ul&gt;&lt;li&gt;&lt;p&gt;Meebo – on-line chat client&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://www.meebo.com/"&gt;http://www.meebo.com/&lt;/a&gt;&lt;/p&gt;  &lt;/li&gt;&lt;/ul&gt;  &lt;/li&gt;&lt;li&gt;&lt;p&gt;37 Signals – Basecamp, Campfire, Backpack, Writeboard,  Ta-da List&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://www.37signals.com/"&gt;http://www.37signals.com/&lt;/a&gt;&lt;/p&gt;  &lt;/li&gt;&lt;/ul&gt;  &lt;/li&gt;&lt;li&gt;&lt;p&gt;Wanna know what people said in Manhattan? Overplot&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://persistent.info/overplot/"&gt;http://persistent.info/overplot/&lt;/a&gt;&lt;/p&gt;  &lt;/li&gt;&lt;/ul&gt;  &lt;/li&gt;&lt;li&gt;&lt;p&gt;Banned books&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://www.applefritter.com/bannedbooks"&gt;http://www.applefritter.com/bannedbooks&lt;/a&gt;&lt;/p&gt;  &lt;/li&gt;&lt;/ul&gt;  &lt;/li&gt;&lt;li&gt;&lt;p&gt;Map World of Warcraft&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://mapwow.com/"&gt;http://mapwow.com/&lt;/a&gt;&lt;/p&gt;  &lt;/li&gt;&lt;/ul&gt;  &lt;/li&gt;&lt;li&gt;&lt;p&gt;Interactive Transit Map&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://www.brail.org/transit/nyc.html"&gt;http://www.brail.org/transit/nyc.html&lt;/a&gt;&lt;/p&gt;   &lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://www.brail.org/transit/london.html"&gt;http://www.brail.org/transit/london.html&lt;/a&gt;&lt;/p&gt;  &lt;/li&gt;&lt;/ul&gt;  &lt;/li&gt;&lt;li&gt;&lt;p&gt;The World's most talked about videos – Viral Video Chart&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://www.viralvideochart.com/"&gt;http://www.viralvideochart.com/&lt;/a&gt;&lt;/p&gt;  &lt;/li&gt;&lt;/ul&gt;  &lt;/li&gt;&lt;li&gt;&lt;p&gt;Chicago Crime – a free browsable database of crimes  reported in Chicago&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://www.chicagocrime.org/"&gt;http://www.chicagocrime.org/&lt;/a&gt;&lt;/p&gt;  &lt;/li&gt;&lt;/ul&gt;  &lt;/li&gt;&lt;li&gt;&lt;p&gt;Zoom In – the best way to explore Australia and New Zealand&lt;/p&gt;  &lt;ul&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://www.zoomin.com.au/"&gt;http://www.zoomin.com.au/&lt;/a&gt;&lt;/p&gt;   &lt;/li&gt;&lt;li&gt;&lt;p&gt;&lt;a href="http://www.zoomin.co.nz/"&gt;http://www.zoomin.co.nz/&lt;/a&gt;&lt;/p&gt;  &lt;/li&gt;&lt;/ul&gt; &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;If you have any other cool link related to cool web sites, post them in your comment to this blog post.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-6593536148193605005?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/6593536148193605005/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=6593536148193605005' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6593536148193605005'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6593536148193605005'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/10/cool-links-from-web-directions-south.html' title='Cool Links from Web Directions South 2006'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-5216403170353595373</id><published>2006-10-02T20:04:00.000+10:00</published><updated>2006-10-02T20:12:12.636+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wd06'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Designing for lifestyle</title><content type='html'>&lt;p&gt;Getting inside the minds of customers is essential for achieving the "aha" effect. More importantly, don't listen to what your customers say! Observe what they do!&lt;/p&gt;  &lt;p&gt;When there are people and machines we get four different types of communication:&lt;/p&gt; &lt;ul&gt;&lt;li&gt;human to human: touch, words, voice;&lt;/li&gt;&lt;li&gt;human to machine: input devices, touch (mouse, keyboard);&lt;/li&gt;&lt;li&gt;machine to machine: binary communication, exchange of XML  documents;&lt;/li&gt;&lt;li&gt;machine to human: GUI communication.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;When it comes to machine to human communication, is it important that we pay attention? There could be messages such as an engine light turns on in the car. It is our role, the role of software developers, to make these messages user-friendly. Otherwise the messages will be ignored or overlooked.&lt;/p&gt;  &lt;p&gt;We have seen that AJAX can fail in keeping the user informed - the message does not make it through. It could be a case when a user votes on something, the request is made but the page does not get reloaded, so we need to highlight the fact that the vote was processed. The question is how to do it so the user sees it without affecting other "more important" things that the user is currently doing on the (same) page.&lt;/p&gt;  &lt;p&gt;There has been a lot of work done in improving the user experience. Starting from Eliza chat bot and the subservient chicken in 2004 to today's websites that are very user-friendly: JetBlue, TiVo, Google, Apple.&lt;/p&gt;  &lt;p&gt;It is all about designing an appropriate user experience. It's also about finding the fine line between practical and emotional (are you emotionally attached to this, do you find this useful, etc.)&lt;/p&gt;&lt;p style="font-weight: bold;"&gt;Practical&lt;/p&gt;&lt;ul&gt;&lt;li&gt;learnable&lt;/li&gt;&lt;li&gt; cost effective&lt;/li&gt;&lt;li&gt;functional &lt;/li&gt;&lt;li&gt; meets the needs&lt;/li&gt;&lt;li&gt;trustworthy &lt;/li&gt;&lt;/ul&gt;&lt;p style="font-weight: bold;"&gt;Emotional&lt;/p&gt;&lt;ul&gt;&lt;li&gt;customizable &lt;/li&gt;&lt;li&gt;unique &lt;/li&gt;&lt;li&gt;aesthetic &lt;/li&gt;&lt;li&gt; meets desires&lt;/li&gt;&lt;li&gt;compelling &lt;/li&gt;&lt;/ul&gt;&lt;p&gt;The real deal is that one you are able to break into people's habits and make them to use your application as a part of their daily rituals (not really an addiction), you will be successful.&lt;/p&gt;  &lt;p&gt;Some of the interesting statistics mentioned were how the usage of mobile phones changed people's rituals and how these technologies saturated the market (Japan 90%, Korea 83%, Europe 68%, US 48%, world-wide 28%). I can see a great potential for growth here in Australia too. And there are some serious money too. In the US, 12-18 year-old kids spend around $4900 a year, which 48% of that is on mobiles (in China it is less than $100 a year). It was also interesting how people use their phones/devices. In US they are called cell phones (amongst popular ones are Palm and Blackberry). In EU and Australia they are called mobile phones and other brands and models are more popular (Nokia, Ericsson). In Singapore however, people may even have two of them. One that is more of a fashion statement and may not even look like a phone.&lt;/p&gt;  &lt;p&gt;There is also a gap between what people think and how people live. As an example, you think that all people would wash their hands after using the toilet, but not all people do. We know that we develop applications and we can think of the ways people will use them. But people are very creative and they use our applications even in unimaginable ways. It's about going through the stages:&lt;/p&gt;&lt;p&gt;"I'm ready to try this out" -&amp;gt; PERCEPTION -&amp;gt; INTERACTION -&amp;gt; INTEGRATION -&amp;gt; "This works for me!"&lt;/p&gt;&lt;p&gt;And what is next? Web 3.0. Global brain = something like a combination of shared data and a search engine aggregating the knowledge spread all over the web.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-5216403170353595373?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/5216403170353595373/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=5216403170353595373' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/5216403170353595373'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/5216403170353595373'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/10/designing-for-lifestyle.html' title='Designing for lifestyle'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-4721333685900766122</id><published>2006-10-02T19:57:00.000+10:00</published><updated>2006-10-02T20:03:20.827+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='social'/><category scheme='http://www.blogger.com/atom/ns#' term='virtual'/><category scheme='http://www.blogger.com/atom/ns#' term='network'/><category scheme='http://www.blogger.com/atom/ns#' term='wd06'/><category scheme='http://www.blogger.com/atom/ns#' term='youbiquity'/><title type='text'>You-biquity</title><content type='html'>&lt;p&gt;From my notes on &lt;a href="http://blog.futurestreetconsulting.com/"&gt;Mark Pesce&lt;/a&gt;'s presentation on You-biquity at &lt;a href="http://www.webdirections.org/"&gt;Web Directions&lt;/a&gt; conference.&lt;/p&gt;&lt;p&gt;Virtual reality isn’t the television of the future, it is the telephone of the future.&lt;/p&gt;  &lt;h3&gt;Part 1: Human Essence&lt;/h3&gt;&lt;p&gt;Right now anything is possible. Humans and chimpanzees are at least 98% identical. We have now found the gene that gives us a bigger brain than our chimpanzee cousins. Both chimps and humans are incredibly social creatures. These social qualities we have as humans are essential to our lives. We build our relationships, we build social hierarchies, we are very social. Social modeling happens in the neocortex of the brain, of which we have more than any other animal. The Dunbar Number: the number of people you can hold in your head is directly relative to the size of neocortex. The reason we have a bigger brain than chimpanzees is to hold a bigger social network in our heads and that is what being human is all about.&lt;/p&gt;&lt;h3&gt;Part 2: Virtual Networks&lt;/h3&gt;&lt;p&gt;Social network needs to be fed fresh data, otherwise it dies. We need to spend time to feed them the data and the time is the non-renewable resource in the 21&lt;sup&gt;st&lt;/sup&gt; century. My social network could be used as my spam filter – if an e-mail is not from a third-degree contact then it's highly suspicious. Wouldn't that be cool! E-mail forwarding is an ad-hoc social network. We find things, we filter them and then we forward them – three F's. For every moment we spend on-line we create a massive amount of data – a data shadow. This data tells a lot about us but at the moment all of then is wasted, not used at all. The mashups are in the right directions, but we need more to use our data to the maximum. The Web is the universal glue.&lt;/p&gt;&lt;h3&gt;Part 3: The Center of the World&lt;/h3&gt;&lt;p&gt;People form a strong relationships with their mobile phones. The phone has become seamlessly integrated into our lives. And the relationship is very emotional. We say we don't have an emotional relationship with our phone but we all lie. Just drop your phone down to the toilet or on the floor and see what happens. I lost my social life! The phone ultimately meets the physical and virtual worlds. For most of the time the phone does nothing. It just waits. What a waste! Imagine if we could use it as a device that listens actively and automatically connects us with the friends that are near.&lt;/p&gt;    &lt;p&gt;The street finds it’s own use for things, uses its makers never intended.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-4721333685900766122?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/4721333685900766122/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=4721333685900766122' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4721333685900766122'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4721333685900766122'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/10/you-biquity.html' title='You-biquity'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-6972762344196891072</id><published>2006-10-02T19:43:00.000+10:00</published><updated>2006-10-02T19:51:15.156+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='wd06'/><category scheme='http://www.blogger.com/atom/ns#' term='search'/><category scheme='http://www.blogger.com/atom/ns#' term='mapping'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><category scheme='http://www.blogger.com/atom/ns#' term='mashup'/><title type='text'>Web APIs</title><content type='html'>&lt;p&gt;Web APIs are sexier that desktop APIs. Having an API allows the external developers to access your data or your services in a smart way. They can they use your data or services in ways you would not imagine.&lt;/p&gt;&lt;p&gt;Currently it is very popular to use the data with mapping APIs. At the moment the &lt;a href="http://maps.google.com/"&gt;Google Maps&lt;/a&gt; have the best and most detailed images of Australia. Microsoft competes with &lt;a href="http://www.microsoft.com/virtualearth/"&gt;Virtual Earth&lt;/a&gt;, they have good images, good maps, but a very restrictive licensing. &lt;a href="http://maps.yahoo.com/"&gt;Yahoo! Maps&lt;/a&gt; has also good images and also gives a choice of Flash or JavaScript. They also provide an option of a static image. The downside of Yahoo! Maps is the lack of mapping information.&lt;/p&gt;&lt;p&gt;Another popular category of APIs is Search. Search APIs can provide cache access, spell-checking, content analysis and much more. Amazon's API offers search on prices, images, customer reviews and affiliate sales.&lt;/p&gt;&lt;p&gt;A good resource for Web APIs is &lt;a href="http://www.programmableweb.com/"&gt;ProgrammableWeb&lt;/a&gt;, which acts as an encyclopedia of available APIs and how people use them.&lt;/p&gt;&lt;p&gt;Mashups are novel UI that enhance your data, e. g. by combining your local data with mapping information. &lt;a href="http://www.chicagocrime.org/"&gt;Chicagocrime.org&lt;/a&gt; – one of the first map mashups was built prior to Google’s API being made public. It’s not all about maps – TagTV, &lt;a href="http://www.viralvideochart.com/"&gt;Viral Video Chart&lt;/a&gt;, BlueOrganizer, Salesforce Adwords.&lt;/p&gt;&lt;p&gt;There are two general types of APIs: interfaces (maps) and data types (the rest). For example  Google Maps are very simple to include; just drop in the script, add four lines of JavaScript and you are done. The other APIs are simply a request to a web resource via HTTP. XML is often used to return the result, though JSON is becoming more popular. These can also be called directly from JavaScript using the XMLHttpRequest object.&lt;/p&gt;&lt;p&gt;The current limitations several. You are limited to the functionality that the provider makes available, unless you screen scrape. There are also concerns with automated collection of personal data, licenses and the changes in terms of use (what will you do if Google Maps is no longer available). We also need to standardize. There are some APIs available that abstract the mapping API access and allow you to switch between Google Maps, Yahoo Maps, etc. Cross domain AJAX is also a security risk. Images, CSS and JavaScript can be loaded from other damains, but HTML or XML can not. A workaround could a proxy server, but this could be a bottleneck if not cached. JSON-P is another alternative, currently supports GET requests, but fails silently if you get the API URL wrong.&lt;/p&gt;&lt;p&gt;In the future we can see ContextAgnosticXmlHttpRequest, enhanced JSON – JSONRequest. Web APIs are all about work we do not have to do. So open your data, offer an API, let the others do the work!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-6972762344196891072?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/6972762344196891072/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=6972762344196891072' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6972762344196891072'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/6972762344196891072'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/10/web-apis.html' title='Web APIs'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-1718039635366610520</id><published>2006-10-02T19:36:00.000+10:00</published><updated>2006-10-02T19:43:44.850+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='hijax'/><category scheme='http://www.blogger.com/atom/ns#' term='wd06'/><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Hijax</title><content type='html'>&lt;p&gt;How can we make feature-rich web site and also offer the way so people with disabilities can access it?&lt;/p&gt;&lt;p&gt;The old way it to produce two version of the website, e. g. Flesh version and HTML only versions. The big drawback of this approach is that the user is presented with the choices first and only then the user enters the website with content. Or some sort of client-side script is run in order to determine the capabilities of the browser. There is no way easy way check the user this way (e. g. the user is blind). Therefore we have a behavior that can be switched ON or OFF.&lt;/p&gt;&lt;p&gt;A better way is progressive enhancement. Initially we have content that we want to publish or present. Then we have the markup – (X)HTML. We add the presentation layer – CSS. At last we add the behavior on top – DOM Scripting.&lt;/p&gt;&lt;p style="margin-bottom: 0cm;"&gt;We still have to answer whether we have some of the functionality in-line or external (*.css and *.js files).&lt;/p&gt;&lt;p&gt;The HIJAX way is :&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;Begin by creating a website using traditional page refreshes,&lt;/li&gt;&lt;li&gt;Data is sent to the server via links and form submissions: the server returns updated pages,&lt;/li&gt;&lt;li&gt;Intercept (hijack) those links and forms using (unobtrusive) JavaScript,&lt;/li&gt;&lt;li&gt;Send that data to &lt;code&gt;XMLHttpRequest&lt;/code&gt; instead of the server,&lt;/li&gt;&lt;li&gt;The server returns just the information that's required instead of an entire page,&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;We have a choice of data format:&lt;/p&gt;&lt;p&gt;&lt;ul&gt;&lt;li&gt;XML + DOM methods&lt;/li&gt;&lt;li&gt;JSON + &lt;code&gt;eval()&lt;/code&gt;&lt;/li&gt;&lt;li&gt;HTML + &lt;code&gt;innerHTML&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/p&gt;&lt;p&gt;Another important thing is that the browser is an unpredictable environment. The user can be running on any OS with any type of web browser. The only thing that we know is what is on our server. Therefore all business logic should be kept on the server side. For example a table sorting can be done on the client-side by JavaScript. This would off-load the server, but we would have to face the challenges with the differences between JavaScript support on various browsers. On top of that we would have no feedback about the usage of table sorting. If this logic was on the server, we could collect the data about table sorting and improve the website accordingly.&lt;/p&gt;&lt;p&gt;The main benefits of using Hijax approach are that we do not need to spend time building a non-Ajax version. Our web application will be still accessible in the usual way. We do not duplicate the logic (client-side and server-side validation) and the links are spiderable and potentially bookmarkable.&lt;/p&gt;&lt;p&gt;HIJAX is a term coined by. I learnt about Hijax at the &lt;a href="http://www.webdirections.org/"&gt;Web Directions&lt;/a&gt; conference. Jeremy Keith presented &lt;a href="http://domscripting.com/presentations/wd06/hijax/"&gt;Proressive Enhancement with Hijax&lt;/a&gt;. He is an author of &lt;a href="http://www.amazon.com/DOM-Scripting-Design-JavaScript-Document/dp/1590595335/sr=1-1/qid=1159769253/ref=sr_1_1/104-0436100-4361544?ie=UTF8&amp;s=books"&gt;DOM Scripting: Web Design with JavaScript and the Document Object Model&lt;/a&gt; and currently working on his next book &lt;a href="http://www.amazon.com/Bulletproof-Ajax-Jeremy-Keith/dp/0321472667/sr=1-2/qid=1159769253/ref=sr_1_2/104-0436100-4361544?ie=UTF8&amp;amp;s=books"&gt;Bulletproof Ajax&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-1718039635366610520?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/1718039635366610520/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=1718039635366610520' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1718039635366610520'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1718039635366610520'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/10/hijax.html' title='Hijax'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-4529335472262450136</id><published>2006-10-02T19:32:00.000+10:00</published><updated>2006-10-02T19:34:04.502+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='microformats'/><category scheme='http://www.blogger.com/atom/ns#' term='wd06'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Microformats</title><content type='html'>&lt;p style="margin-bottom: 0cm;"&gt;In these days we turn for the answers to our questions to the Internet. Sometimes we even refer to it as the wisdom of the crowd.&lt;/p&gt;  &lt;p style="margin-bottom: 0cm;"&gt;Take IMDB for example. It is a centralized solution. When it comes to the reviews they are written by the people. But who owns these reviews? Are they real? Can we trust them? Google is the answer to all our prayers. Or as a big sign in front of one church said “Google does not have the answers to all questions.”&lt;/p&gt;  &lt;p style="margin-bottom: 0cm;"&gt;We saw the raise of open source. Then we also had a raise of open standards for document formats. They are getting more popular and also more important. The next step will be the open data. Standardizing the data format will also allow for more mashups. Very popular type of mashup these days is the combination of maps and some other proprietary data. If two people publish the data in two different formats, none of them can make use of the other.&lt;/p&gt;  &lt;p style="margin-bottom: 0cm;"&gt;Web has evolved. The move is from HTML to XHTML. The benefits are such as that microformats are simple data formats, HTML based, based on existing standards and existing development practices. To mention a few, there is hCard (based on vCard), hCalendar (based on iCal), hReview, hListing- for classfields, hResume and many more.&lt;/p&gt;  &lt;p style="margin-bottom: 0cm;"&gt;I also discovered that there are some Firefox extensions that discover microformats on the page and  allow the user to see them. One that is worth mentioning is &lt;a href="http://blog.codeeg.com/tails-firefox-extension-03/"&gt;Tails&lt;/a&gt;.&lt;/p&gt;  &lt;p style="margin-bottom: 0cm;"&gt;Where to do from here? We all publish data on the web. More microformatted data we publish more  options of their usage will be present.&lt;/p&gt;  &lt;p style="margin-bottom: 0cm;"&gt;More information about microformats can be found at &lt;a href="http://microformats.org/"&gt;microformats.org&lt;/a&gt;, &lt;a href="http://microformatique.com/"&gt;microformatique.com&lt;/a&gt;. Read about how to &lt;a href="http://www.hicksdesign.co.uk/journal/highlight-microformats-with-css"&gt;highlight microformats with CSS&lt;/a&gt;. New book on microformats by John Allsopp will be coming out in early 2007.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-4529335472262450136?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/4529335472262450136/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=4529335472262450136' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4529335472262450136'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/4529335472262450136'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/10/microformats.html' title='Microformats'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-2090919397194780204</id><published>2006-10-02T19:26:00.000+10:00</published><updated>2006-10-02T19:32:14.973+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='accessibility'/><category scheme='http://www.blogger.com/atom/ns#' term='wd06'/><category scheme='http://www.blogger.com/atom/ns#' term='html'/><category scheme='http://www.blogger.com/atom/ns#' term='css'/><title type='text'>Web Accessibility</title><content type='html'>&lt;p style="margin-bottom: 0cm;"&gt;I attended the &lt;a href="http://www.webdirections.org/"&gt;Web Directions&lt;/a&gt; conference last week. One of the eye-opening sessions (at least for me) was “Accessibility 2.0” and “Designing for Accessibility: More simple techniques that make a difference” by &lt;a href="http://www.boxofchocolates.ca/"&gt;Derek Featherstone&lt;/a&gt; from &lt;a href="http://furtherahead.com/"&gt;FurtherAhead&lt;/a&gt;.&lt;/p&gt;  &lt;p style="margin-bottom: 0cm;"&gt;Accessibility is about allowing disabled people to use our website. I have never worked on a project that would require access by people with disabilities. I think it really takes a real life experience to realize what these people must go through in their everyday lives. Why should we make it more difficult for them with our web applications? Do you know how many web applications stop working when you switch JavaScript off? You would be surprised to see how big number that is.&lt;/p&gt;  &lt;p style="margin-bottom: 0cm;"&gt;There are some guidelines that we can follow in order to make our websites more accessible. If we remove frames, replace menu images with menu using text and CSS, don't use tables for formatting, we make a big step towards accessibility of our websites. Another thing is having PDF documents on the website. PDFs are not accessible and they also need to be downloaded in order to read them and find out that it's not the document that we wanted. Another place for improvement are the web forms. Fields should have labels.&lt;/p&gt;  &lt;p style="margin-bottom: 0cm;"&gt;The phrase “people with disabilities don't go to our website” is just a nonsense. They do and they can also bring some revenue. Take for example &lt;a href="http://www.tesco.com/access/about.htm"&gt;Tesco Access&lt;/a&gt;. Grocery shopping on the web is an ideal service for visually-impaired customers. Imagine trying to tell a can of beans from a can of tomatoes on the shelf if you can't see the labels. Then think about having the description read to you by your computer. Their website was designed for accessibility and because of this feature it boosted revenue by another 4%.&lt;/p&gt;  &lt;p style="margin-bottom: 0cm;"&gt;Accessibility is personal. Removing barriers, user testing is personal.&lt;/p&gt;  &lt;p style="margin-bottom: 0cm;"&gt;Where do I go from here? Well, I will start at the roots – &lt;a href="http://www.w3.org/WAI/"&gt;W3C Web Accessibility Initiative&lt;/a&gt; and &lt;a href="http://www.access-board.gov/sec508/508standards.htm"&gt;Section 508&lt;/a&gt;. Then I will read &lt;a href="http://diveintoaccessibility.org/"&gt;Dive into Accessibility&lt;/a&gt; book that according to its website answers two questions “Why should I make my web site more accessible?” and “How can I make my web site more accessible?” Australia with its &lt;a href="http://www.hreoc.gov.au/disability_rights/dda_guide/dda_guide.htm"&gt;Disability Discrimination Act&lt;/a&gt; is six years ahead of USA.&lt;/p&gt;  &lt;p style="margin-bottom: 0cm;"&gt;I also found &lt;a href="http://cita.rehab.uiuc.edu/"&gt;The Illinois Center for Instructional Technology Accessibility&lt;/a&gt; very informative. They list the best practices, have software for download (&lt;a href="http://cita.rehab.uiuc.edu/software/mozilla/"&gt;Accessibility Extensions for Mozilla/Firefox&lt;/a&gt; lives here) and lots more. Another great resource for developers is &lt;a href="http://www.ariadne.ac.uk/issue44/lauke/"&gt;Evaluating Web Sites for Accessibility with Firefox&lt;/a&gt; by Patrick H. Lauke.&lt;/p&gt;  &lt;p style="margin-bottom: 0cm;"&gt;Some of these guidelines are very much a checklist approach. User experience is more important. Therefore we need to sit down with the real user, the one that will be using the system, and work together in order to fulfill the user's needs and expectations of this system.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-2090919397194780204?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/2090919397194780204/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=2090919397194780204' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/2090919397194780204'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/2090919397194780204'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/10/web-accessibility.html' title='Web Accessibility'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-87193546623550974</id><published>2006-10-02T17:10:00.000+10:00</published><updated>2007-04-15T21:05:09.418+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='australia'/><category scheme='http://www.blogger.com/atom/ns#' term='wd06'/><category scheme='http://www.blogger.com/atom/ns#' term='web'/><title type='text'>Jeremy Keith presenting in Melbourne</title><content type='html'>&lt;p&gt;&lt;a href="http://webstandardsgroup.org/"&gt;WSG&lt;/a&gt; and &lt;a href="http://webdirections.org/"&gt;Web Directions&lt;/a&gt; are hosting a &lt;a href="http://webstandardsgroup.org/meetings/index.cfm?event_id=75"&gt;presentation&lt;/a&gt; by &lt;a href="http://www.clearleft.com/about/jeremy/"&gt;Jeremy Keith&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold;"&gt;When&lt;/span&gt;:&lt;br /&gt;Thursday 05 October 2006 at 6:30pm&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold;"&gt;Where:&lt;/span&gt;&lt;br /&gt;Centre for Innovation &amp;amp; Technology Commercialisation&lt;br /&gt;Level 1, 257 Collins Street&lt;br /&gt;Melbourne VIC 3000&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-87193546623550974?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/87193546623550974/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=87193546623550974' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/87193546623550974'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/87193546623550974'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/10/jeremy-keith-presenting-in-melbourne.html' title='Jeremy Keith presenting in Melbourne'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-1961458226215421055</id><published>2006-10-02T14:56:00.001+10:00</published><updated>2006-10-02T14:56:52.057+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wd06'/><category scheme='http://www.blogger.com/atom/ns#' term='quote'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>Quotes that made me laugh today</title><content type='html'>&lt;p&gt;A funny quote that came out of &lt;a href="http://www.webdirections.org/"&gt;Web Directions&lt;/a&gt; conference.&lt;/p&gt;&lt;p&gt;&lt;q&gt;The web isn’t a power drill!&lt;/q&gt; - &lt;cite&gt;Andy Clarke&lt;/cite&gt;&lt;br /&gt;&lt;q&gt;It’s a series of tubes!&lt;/q&gt; - &lt;cite&gt;John Allsopp&lt;/cite&gt;&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-1961458226215421055?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/1961458226215421055/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=1961458226215421055' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1961458226215421055'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/1961458226215421055'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/10/quotes-that-made-me-laugh-today.html' title='Quotes that made me laugh today'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115953899752555505</id><published>2006-09-29T23:00:00.000+10:00</published><updated>2006-09-30T00:09:57.546+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='australia'/><category scheme='http://www.blogger.com/atom/ns#' term='conference'/><category scheme='http://www.blogger.com/atom/ns#' term='flickr'/><category scheme='http://www.blogger.com/atom/ns#' term='wd06'/><title type='text'>How we built Flickr  workshop and Web Directions North conference</title><content type='html'>I just came home after a two-day &lt;a href="http://www.webdirections.org/"&gt;Web Directions South 2006&lt;/a&gt; conference. This conference was a huge success. I will blog about it more later. What is next? Well, there is going to be a &lt;a href="http://north.webdirections.org/"&gt;Web Directions North&lt;/a&gt; conference in Vancouver in 6-10 February next year. And if you look at the schedule, there is some skiing and boarding planned as well... just get your boss to pay for it :-)&lt;br /&gt;&lt;br /&gt;This is a link to the upcoming one-day workshop presented by Cal Henderson on &lt;a href="http://www.webworkshops.com.au/flickr"&gt;Building Enterprise Web Apps on a Budget - How We Built Flickr&lt;/a&gt; organized by &lt;a href="http://www.webworkshops.com.au/"&gt;webworkshops&lt;/a&gt;.&lt;br /&gt;&lt;br /&gt;It is scheduled as following:&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Brisbane&lt;/span&gt; 13 November 2006&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Sydney&lt;/span&gt; 14 November 2006&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Canberra&lt;/span&gt; 16 November 2006&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Melbourne&lt;/span&gt; 17 November 2006&lt;br /&gt;&lt;br /&gt;Hope to see you there!&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115953899752555505?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115953899752555505/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115953899752555505' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115953899752555505'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115953899752555505'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/09/how-we-built-flickr-workshop-and-web.html' title='How we built Flickr  workshop and Web Directions North conference'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115945575323693317</id><published>2006-09-29T00:35:00.000+10:00</published><updated>2006-09-29T08:07:48.053+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='blog'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Have you Googled Yourself?</title><content type='html'>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/1127815642.0.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/200/1127815642.0.jpg" alt="" border="0" /&gt;&lt;/a&gt; As John DellaContrada an UB Internet-Culture Expert says in his &lt;a href="http://www.buffalo.edu/news/fast-execute.cgi/article-page.html?article=66380009"&gt;"Self-Googling" Isn't Just Vanity; It's a Shrewd Form of Personal "Brand Management"&lt;/a&gt;&lt;/p&gt;&lt;blockquote&gt;"Self-Googling" -- searching for your own name on the popular Google search engine -- may seem like an innocuous act of vanity, but a University at Buffalo communications professor recommends it as a shrewd form of "personal brand management" in the digital age.&lt;/blockquote&gt;&lt;p&gt;I don't do this much, but how can I resist? I write this blog and few other things in other places so I wondered what people find when they search my name. So &lt;a href="http://www.google.com/search?q=hanuska&amp;start=0&amp;amp;amp;amp;ie=utf-8&amp;oe=utf-8&amp;amp;client=firefox-a&amp;amp;rls=org.mozilla:en-US:official"&gt;I googled my surname...&lt;/a&gt; I got 7 out of 10 results on the first page.&lt;/p&gt;&lt;p&gt;And as John DellaContrada consludes&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;"Starting your own Weblog or Web site can help you to shape your public image, and make sure that it accurately reflects your abilities and interests."&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;So what are you waiting for? Go out there and start writing!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115945575323693317?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115945575323693317/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115945575323693317' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115945575323693317'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115945575323693317'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/09/have-you-googled-yourself.html' title='Have you Googled Yourself?'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115945227922503585</id><published>2006-09-28T23:34:00.000+10:00</published><updated>2006-09-29T01:08:24.793+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='accessibility'/><category scheme='http://www.blogger.com/atom/ns#' term='wd06'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><title type='text'>Good Design in Practice</title><content type='html'>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/96709053_51b41a249f_s.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/200/96709053_51b41a249f_s.jpg" alt="" border="0" /&gt;&lt;/a&gt; I attended the first day of the &lt;a href="http://www.webdirections.org/"&gt;Web Directions South 2006&lt;/a&gt; conference today. Some of the topics that were covered today were about the design of the web sites and web pages or the design in general. Since I read &lt;a href="http://www.amazon.com/Design-Everyday-Things-Donald-Norman/dp/0465067107/sr=8-1/qid=1159450313/ref=pd_bbs_1/104-0436100-4361544?ie=UTF8&amp;s=books"&gt;&lt;span style=""&gt;The Design of Everyday Things&lt;/span&gt;&lt;/a&gt; by Donal A. Norman (which I mentioned in one of my previous posts about &lt;a href="http://hanuska.blogspot.com/2006/07/good-design.html"&gt;Good Desing&lt;/a&gt;) I tend to look at things in a different way. And I also appreciate the good design of the things we use. A thing can have all it needs but if not designed well it will fail as it will be unusable (see the cover of the book and you'll get the idea at least – or read the whole book).&lt;/p&gt;&lt;p&gt;There was one of the things that I use in my everyday life, but only today I realized how brilliantly it was designed. &lt;a href="http://www.webdirections.org/whos-speaking/#featherstone"&gt;Derek Featherstone&lt;/a&gt; has apparently same eye as me as he showed us the photo that he took the day before. It was a photo of&lt;/p&gt;&lt;p&gt;&lt;b&gt;The pedestrian crossing button&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/96709053_51b41a249f.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/400/96709053_51b41a249f.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;How perfect it is! Not only you can see the big white arrow but if your eyesight is impaired you can touch and feel the smaller raised arrow. And that is not all! If you cannot see it, you can hear it ticking when the green light is on. And that still is not all! If you cannot see nor hear, you can still feel it. The button VIBRATES!!! Derek said it at the conference and was all excited about it. I did not believe. I had to touch it on my way home from the conference. It is true! It does vibrate!&lt;/p&gt;&lt;p&gt;How cool is that?! That is a successful design in practice. Way to go designers!&lt;/p&gt;&lt;p&gt;What is next? Well, as a software developer I will focus a bit more on designing the web applications in a way that all people can access them, even if they have some disabilities. Sometimes we go and design things that are cool, but not usable by all of us...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115945227922503585?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115945227922503585/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115945227922503585' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115945227922503585'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115945227922503585'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/09/good-design-in-practice.html' title='Good Design in Practice'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115936418186622318</id><published>2006-09-27T23:09:00.000+10:00</published><updated>2007-04-15T21:07:55.554+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='collections'/><category scheme='http://www.blogger.com/atom/ns#' term='iteration'/><category scheme='http://www.blogger.com/atom/ns#' term='list'/><category scheme='http://www.blogger.com/atom/ns#' term='best practice'/><category scheme='http://www.blogger.com/atom/ns#' term='element'/><title type='text'>First element in the List</title><content type='html'>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/75559623_6f4c208f8c_s.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/200/75559623_6f4c208f8c_s.jpg" alt="" border="0" /&gt;&lt;/a&gt;Imagine this scenario. You are working on an existing application. There is a framework used. One of the benefits that this framework gives you is retrieving and processing parameters coming from the client, let's say a web application. The framework gives you all parameters as a &lt;code&gt;List&lt;/code&gt;. Now in this particular case you always get only one parameter, but is it enclosed in the List. How do you get it out efficiently?&lt;/p&gt;&lt;p&gt;The intended method would be described: &lt;cite&gt;Get the list of parameters and if not empty, return first element in the list otherwise return null.&lt;/cite&gt; The code was looked similar to this:&lt;/p&gt;&lt;pre&gt;&lt;code style="color: Blue;"&gt;1 public E getSingleParam(List&lt;e&gt;&lt;e&gt;&lt;e&gt; params) {&lt;br /&gt;2     E param = null;&lt;br /&gt;3     if (params != null &amp;&amp;amp; params.size() &gt;= 1) {&lt;br /&gt;4         param = params.iterator().next();&lt;br /&gt;5     }&lt;br /&gt;6 }&lt;/e&gt;&lt;/e&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This code works fine but it has several points for improvement. First is how the code at line 3 expresses the intention of check whether the list of parameters is not null and not empty, specifically the later. List interface defines boolean &lt;code&gt;isEmpty()&lt;/code&gt; method that is in most cases more efficient to run than getting the size and comparing it to 0 (greater than) or 1 (grater than or equal). That is if the list implements an internal flag for its "emptiness" state or has an internal counter as opposed to re-counting its elements. In the worst case scenario the efficiency will be the same as getting the size and comparing it with 0. In that case &lt;code&gt;isEmpty()&lt;/code&gt; method is still a nice convenience method to call and should be preferred before the &lt;code&gt;size() &gt; 0&lt;/code&gt; alternative. Another reason is that it speaks for itself. All we need to know is whether there are any elements in the list or not. Getting the size should be used to for other purposes (e.g. calculating the width of the table column when displaying the results in a tabular form – &lt;code&gt;100% / size()&lt;/code&gt;).&lt;/p&gt;&lt;pre&gt;&lt;code style="color: Blue;"&gt;1 public E getSingleParam(List&lt;e&gt;&lt;e&gt;&lt;e&gt; params) {&lt;br /&gt;2     E param = null;&lt;br /&gt;3     if (params != null &amp;&amp;amp; !params.isEmpty()) {&lt;br /&gt;4         param = params.iterator().next();&lt;br /&gt;5     }&lt;br /&gt;6 }&lt;/e&gt;&lt;/e&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The second point of making the code to perform better and to make it easier to read is the line 4. On this line we are getting the first element of the list. As shown in the example above, this is an inefficient way as we construct an Iterator only for the purpose of one iteration. Constructing new objects and disposing of them is usually expensive and should be avoided. A better way is to access the element directly, such as:&lt;/p&gt;&lt;pre&gt;&lt;code style="color: Blue;"&gt;1 public E getSingleParam(List&lt;e&gt;&lt;e&gt;&lt;e&gt; params) {&lt;br /&gt;2     E param = null;&lt;br /&gt;3     if (params != null &amp;&amp;amp; !params.isEmpty()) {&lt;br /&gt;4         param = params.get(0);&lt;br /&gt;5     }&lt;br /&gt;6 }&lt;/e&gt;&lt;/e&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This way no new objects are constructed (no &lt;code&gt;Iterator&lt;/code&gt;). Another difference between the two is the exception that could be possibly thrown. The exception would be thrown if we did not have the previous check or in the case of concurrent modification of the list which is very unlikely in this case. The exception thrown in first case would be a &lt;span style="font-weight: bold;"&gt;NoSuchElementException&lt;/span&gt;. In the second way, an &lt;span style="font-weight: bold;"&gt;IndexOutOfBoundsException&lt;/span&gt; would be thrown. Both of them are runtime exceptions and do not have to be declared. In this case getting one exception or the other should not make any difference.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115936418186622318?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115936418186622318/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115936418186622318' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115936418186622318'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115936418186622318'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/09/first-element-in-list.html' title='First element in the List'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115617037648626086</id><published>2006-08-22T00:13:00.000+10:00</published><updated>2007-10-07T10:00:38.140+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='puzzler'/><title type='text'>Tricky instanceof operator</title><content type='html'>&lt;p&gt;Let's start with a little puzzle.&lt;/p&gt;&lt;pre&gt;&lt;code  style="color:Blue;"&gt;Object obj = ...&lt;br /&gt;System.out.println(obj instanceof Object);&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;How do you initialize the obj in order to print "false"?&lt;/p&gt;&lt;p&gt;Well, aren't all possible Java objects instances of Object? To answer this question one must understand how instanceof operator works. The answer is that it would print "true" for any Object. &lt;span style="font-weight: bold;"&gt;The only way to make it false is not to give it an object, give it a null reference.&lt;/span&gt;&lt;/p&gt;&lt;p&gt;The tricky bit about instanceof operator can be that if object on the left side is null, the condition evaluates to false. Therefore there is no need for null check after a class cast as in the following example.&lt;/p&gt;&lt;pre&gt;&lt;code  style="color:Blue;"&gt;public boolean equals(Object o) {&lt;br /&gt;  if (o instanceof MyClass) {&lt;br /&gt;    MyClass mc = (MyClass) o;&lt;br /&gt;    if (mc == null) &lt;span style="color:Red;"&gt;// never null&lt;/span&gt;&lt;br /&gt;      return false;&lt;br /&gt;    else&lt;br /&gt;      return ... &lt;span style="color:Gray;"&gt;// compare members of mc&lt;/span&gt;&lt;br /&gt;  }&lt;br /&gt;  return false;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This can be simplified as shown in the following code snippet&lt;/p&gt;&lt;pre&gt;&lt;code style="color:Blue;"&gt;public boolean equals(Object o) {&lt;br /&gt;  if (o instanceof MyClass) {&lt;br /&gt;    MyClass mc = (MyClass) o;&lt;br /&gt;    return ... &lt;span style="color:Gray;"&gt;// compare members of mc&lt;/span&gt;&lt;br /&gt;  }&lt;br /&gt;  return false;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;So the moral if this excercise is that instanceof operator works as you would expect with objects, and returns false when given a null.&lt;/p&gt;&lt;p&gt;And remember that equals() method is probably the only reasonable place for instanceof operator. If you do it elsewhere and use it to create an alternative flow (e.g. if-else, switch) it is a bad smell and should be replaced with polymorphism. Read more about &lt;a href="http://hanuska.blogspot.com/2006/08/swich-statement-code-smell-and.html"&gt;Swich Statement code smell and Polymorphism&lt;/a&gt;&lt;/p&gt;&lt;p&gt;BTW the previous example was not a very nice example of how to implement equals method, so do not copy it ;-) Usually we would do something like this&lt;/p&gt;&lt;pre&gt;&lt;code style="color: Blue;"&gt;public boolean equals(Object o) {&lt;br /&gt;  if (o == null) return false;&lt;br /&gt;  if (o == this) return true;&lt;br /&gt;  if (!(o instanceof MyClass)) return false;&lt;br /&gt;  MyClass mc = (MyClass) o;&lt;br /&gt;  return ... &lt;span style="color:Gray;"&gt;// compare members of mc&lt;/span&gt;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115617037648626086?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115617037648626086/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115617037648626086' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115617037648626086'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115617037648626086'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/08/tricky-instanceof-operator.html' title='Tricky instanceof operator'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115596820104142887</id><published>2006-08-19T16:08:00.000+10:00</published><updated>2006-12-27T20:36:54.375+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>Swich Statement code smell and Polymorphism</title><content type='html'>&lt;p&gt;One of the symptoms of object-oriented programming is the lack of &lt;code&gt;switch&lt;/code&gt; or &lt;code&gt;case&lt;/code&gt; statements. Imagine that we have some client class that calculates the area and perimeter of particular geometrical shapes.&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;code color="Blue"&gt;public class Client {&lt;br /&gt; private double &lt;strong&gt;a&lt;/strong&gt;;&lt;br /&gt; private double &lt;strong&gt;b&lt;/strong&gt;;&lt;br /&gt; private double &lt;strong&gt;r&lt;/strong&gt;;&lt;br /&gt; ...&lt;br /&gt; public double calculateArea(int shape) {&lt;br /&gt;     double area = 0;&lt;br /&gt;     switch(shape) {&lt;br /&gt;         case SQUARE:&lt;br /&gt;             &lt;strong&gt;area = a * a;&lt;/strong&gt;&lt;br /&gt;             break;&lt;br /&gt;         case RECTANGLE:&lt;br /&gt;             &lt;strong&gt;area = a * b;&lt;/strong&gt;&lt;br /&gt;             break;&lt;br /&gt;         case CIRCLE:&lt;br /&gt;             &lt;strong&gt;area = Math.PI * r * r;&lt;/strong&gt;&lt;br /&gt;             break;&lt;br /&gt;     }&lt;br /&gt;     return area;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public double calculatePerimeter(int shape) {&lt;br /&gt;     double perimeter = 0;&lt;br /&gt;     switch(shape) {&lt;br /&gt;         case SQUARE:&lt;br /&gt;             &lt;strong&gt;perimeter = 4 * a;&lt;/strong&gt;&lt;br /&gt;             break;&lt;br /&gt;         case RECTANGLE:&lt;br /&gt;             &lt;strong&gt;perimeter = 2 * (a + b);&lt;/strong&gt;&lt;br /&gt;             break;&lt;br /&gt;         case CIRCLE:&lt;br /&gt;             &lt;strong&gt;perimeter = 2 * Math.PI * r;&lt;/strong&gt;&lt;br /&gt;             break;&lt;br /&gt;     }&lt;br /&gt;     return perimeter;&lt;br /&gt; }&lt;br /&gt; ...&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The previous code is clearly a poor design that limits the current client to only work with three types of shapes. The problem with &lt;code&gt;switch&lt;/code&gt; statements is the &lt;strong&gt;duplication&lt;/strong&gt; and that is a code smell. There are usually several places in the code where the behaviour slightly deviates and these &lt;code&gt;switch&lt;/code&gt; statements are present (e.g. in &lt;code&gt;calculateArea&lt;/code&gt; and &lt;code&gt;calculatePerimeter&lt;/code&gt; methods). Even worse case is if we work with objects where the &lt;code&gt;switch&lt;/code&gt; is replaced by multiple &lt;code&gt;instanceof&lt;/code&gt; conditions.&lt;/p&gt;&lt;pre&gt;&lt;code color="Blue"&gt;&lt;br /&gt;public class Client {&lt;br /&gt; ...&lt;br /&gt; public double calculateArea(Object shape) {&lt;br /&gt;     double area = 0;&lt;br /&gt;     if (&lt;strong&gt;shape instanceof Square&lt;/strong&gt;) {&lt;br /&gt;         Square square = (Square) shape;&lt;br /&gt;         area = square.getA() * square.getA();&lt;br /&gt;     }&lt;br /&gt;     else if (&lt;strong&gt;shape instanceof Rectangle&lt;/strong&gt;) {&lt;br /&gt;         Rectangle rectangle = (Rectangle) shape;&lt;br /&gt;         area = rectangle.getA() * rectangle.getB();&lt;br /&gt;     }&lt;br /&gt;     else if (&lt;strong&gt;shape instanceof Circle&lt;/strong&gt;) {&lt;br /&gt;         Circle circle = (Circle) shape;&lt;br /&gt;         area = Math.PI * cirle.getR() * cirle.getR();&lt;br /&gt;     }&lt;br /&gt;     return area;&lt;br /&gt; }&lt;br /&gt;&lt;br /&gt; public double calculatePerimeter(Object shape) {&lt;br /&gt;     double perimeter = 0;&lt;br /&gt;     if (&lt;strong&gt;shape instanceof Square&lt;/strong&gt;) {&lt;br /&gt;         Square square = (Square) shape;&lt;br /&gt;         perimeter = 4 * square.getA();&lt;br /&gt;     }&lt;br /&gt;     else if (&lt;strong&gt;shape instanceof Rectangle&lt;/strong&gt;) {&lt;br /&gt;         Rectangle rectangle = (Rectangle) shape;&lt;br /&gt;         perimeter = 2 * (rectangle.getA() + rectangle.getB());&lt;br /&gt;     }&lt;br /&gt;     else if (&lt;strong&gt;shape instanceof Circle&lt;/strong&gt;) {&lt;br /&gt;         Circle circle = (Circle) shape;&lt;br /&gt;         perimeter = 2 * Math.PI * cirle.getR();&lt;br /&gt;     }&lt;br /&gt;     return perimeter;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To improve the desing we make &lt;code&gt;Square&lt;/code&gt;, &lt;code&gt;Rectangle&lt;/code&gt; and &lt;code&gt;Circle&lt;/code&gt; have a commont root. By that I mean that they either extend the same class, such as &lt;code&gt;AbstractShape&lt;/code&gt; or that they implement a common interface, such as &lt;code&gt;Shape&lt;/code&gt; or ideally both.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/ClassDiagram1.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/400/ClassDiagram1.0.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Then we can eliminate the switch statement code smell very easily. We replace it with polymorphism.&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;&lt;code style="color: Blue;"&gt;&lt;span style="color:Gray;"&gt;Shape.java file&lt;/span&gt;&lt;br /&gt;public interface &lt;strong&gt;Shape&lt;/strong&gt; {&lt;br /&gt; &lt;strong&gt;public double getArea();&lt;/strong&gt;&lt;br /&gt; &lt;strong&gt;public double getPerimeter();&lt;/strong&gt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:Gray;"&gt;Square.java file&lt;/span&gt;&lt;br /&gt;public class &lt;strong&gt;Square&lt;/strong&gt; implements Shape {&lt;br /&gt; private double a;&lt;br /&gt; ...&lt;br /&gt; public double getArea() {&lt;br /&gt;     return a * a;&lt;br /&gt; }&lt;br /&gt; public double getPerimeter() {&lt;br /&gt;     return 4 * a;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:Gray;"&gt;Rectangle.java file&lt;/span&gt;&lt;br /&gt;public class &lt;strong&gt;Rectangle&lt;/strong&gt; implements Shape {&lt;br /&gt; private double a;&lt;br /&gt; private double b;&lt;br /&gt; ...&lt;br /&gt; public double getArea() {&lt;br /&gt;     return a * b;&lt;br /&gt; }&lt;br /&gt; public double getPerimeter() {&lt;br /&gt;     return 2 * (a + b);&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span style="color:Gray;"&gt;Circle.java file&lt;/span&gt;&lt;br /&gt;public class &lt;strong&gt;Circle&lt;/strong&gt; implements Shape {&lt;br /&gt; private double r;&lt;br /&gt; ...&lt;br /&gt; public double getArea() {&lt;br /&gt;     return Math.PI * r * r;&lt;br /&gt; }&lt;br /&gt; public double getPerimeter() {&lt;br /&gt;     return 2 * Math.PI * r;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And such refactoring simplifies the &lt;code&gt;Client&lt;/code&gt; code. It also allows for easy extensibility by implementations of other shapes without changing a single line of &lt;code&gt;Client&lt;/code&gt; code.&lt;/p&gt;&lt;pre&gt;&lt;code style="color: Blue;"&gt;public class Client {&lt;br /&gt; private &lt;strong&gt;Shape shape&lt;/strong&gt;;&lt;br /&gt; ...&lt;br /&gt; public double calculateArea() {&lt;br /&gt;     return &lt;strong&gt;shape.getArea()&lt;/strong&gt;;&lt;br /&gt; }&lt;br /&gt; public double calculatePerimeter() {&lt;br /&gt;     return &lt;strong&gt;shape.getPerimeter()&lt;/strong&gt;;&lt;br /&gt; }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Another way of looking at it is from the responsibility point of view. Why should the client be responsible for calculating the area or the perimeter; or have a knowledge about shape's internals (e.g. number of sides, radius, etc.) It is the responsibility of each shape and all that the client needs to know is that a shape has a perimeter and area.&lt;/p&gt;&lt;p&gt;To sum this all up:&lt;br /&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;Use &lt;a href="http://www.refactoring.com/catalog/extractMethod.html"&gt;Extract Method&lt;/a&gt; refactoring to extract the switch statement,&lt;/li&gt;&lt;li&gt;If needed, use &lt;a href="http://www.refactoring.com/catalog/moveMethod.html"&gt;Move Method&lt;/a&gt; refactoring to move the method into the class where the plymorphsm is needed,&lt;/li&gt;&lt;li&gt;Then you can either &lt;a href="http://www.refactoring.com/catalog/replaceTypeCodeWithSubclasses.html"&gt;Replace Type Code with Subclasses&lt;/a&gt; or &lt;a href="http://www.refactoring.com/catalog/replaceTypeCodeWithStateStrategy.html"&gt;Replace Type Code with State/Strategy&lt;/a&gt; pattern,&lt;/li&gt;&lt;li&gt;Finally, when inheritance structure is in place, use &lt;a href="http://www.refactoring.com/catalog/replaceConditionalWithPolymorphism.html"&gt;Replace Conditional with Polymorphism&lt;/a&gt; refactoring.&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115596820104142887?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115596820104142887/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115596820104142887' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115596820104142887'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115596820104142887'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/08/swich-statement-code-smell-and.html' title='Swich Statement code smell and Polymorphism'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115572770733679813</id><published>2006-08-16T20:43:00.000+10:00</published><updated>2006-08-16T21:28:27.360+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='api'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>Programmable Web and GoogleMaps Fligh Simulator</title><content type='html'>&lt;p&gt;Today I came across an iteresting website: &lt;a href="http://programmableweb.com/"&gt;ProgrammableWeb&lt;/a&gt; - &lt;span style="font-style: italic;"&gt;because the world's is your programmable oyster&lt;/span&gt;. In their words:&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;blockquote&gt;&lt;img src="http://programmableweb.com/images/ProgrammableWebLogo.gif" style="margin-left: 10px; float: right;" /&gt; ProgrammableWeb is where you can keep-up with the latest mashups, what's new and interesting with Web 2.0 APIs, and the Web as Platform in general. The core of the site is the blog and the 3 dashboards: Home, Mashups and APIs. All dashboards are updated daily.&lt;/blockquote&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;It's worthwhile having a look at &lt;a href="http://programmableweb.com/apis"&gt;API&lt;/a&gt; part. And this is how I found&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.isoma.net/games/goggles.html"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/320/goggles.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Quite nice app, good fun exploring the world without being scared of terrorism! And as you can see I had a few successful flights over the Sydney Opera House. But be careful! Do not fly too low, you can crash!&lt;/p&gt;&lt;p&gt;&lt;table border="0" width="410"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/goggles2.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/200/goggles2.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;td&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/goggles1.jpg"&gt;&lt;img style="cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/200/goggles1.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115572770733679813?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115572770733679813/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115572770733679813' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115572770733679813'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115572770733679813'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/08/programmable-web-and-googlemaps-fligh.html' title='Programmable Web and GoogleMaps Fligh Simulator'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115545818898648347</id><published>2006-08-13T18:32:00.000+10:00</published><updated>2006-08-13T18:50:50.293+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='collections'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>Improved Map Iteration</title><content type='html'>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/134415596_9cdb092ce2_s.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/320/134415596_9cdb092ce2_s.jpg" alt="" border="0" /&gt;&lt;/a&gt; When some one new to Java comes to play, first thing they do, they re-invent the wheel. Such wheel can be a class that is already implemented in &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/package-summary.html"&gt;java.util&lt;/a&gt; package. Yes! &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Collection.html"&gt;Collections&lt;/a&gt; and &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Map.html"&gt;Maps&lt;/a&gt;! Later, as you become a senior Java developer you alredy know the narrow places in the "Utils" valley. And yet we can make mistakes.&lt;/p&gt;&lt;p&gt;Such mistake can be the following implementation of the method that calculates the size of the collection.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;code  style="color:Blue;"&gt;private Collection myStuff = ...&lt;br /&gt;&lt;br /&gt;public int calculateSize() {&lt;br /&gt;   int count = 0;&lt;br /&gt;   for (Iterator it = myStuff.iterator(); it.hasNext(); it.next()) {&lt;br /&gt;       count++;&lt;br /&gt;   }&lt;br /&gt;   return count;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;This can be easily fixed by&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;code  style="color:Blue;"&gt;public int calculateSize() {&lt;br /&gt;   return myStuff.&lt;span style="color:Red;"&gt;size()&lt;/span&gt;;&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Another, more frequent example of bad performance is a condition where one wants to know if there are any objects in the collection, but does not really care how many there are.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;code  style="color:Blue;"&gt;if (myStuff.size() == 0) {&lt;br /&gt;   // do something&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Remember size() method may possibly calculate the size and therefore generally is slower than a call to isEmpty() method. Therefore the fix is obvious.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;code  style="color:Blue;"&gt;if (myStuff.&lt;span style="color:Red;"&gt;isEmpty()&lt;/span&gt;) {&lt;br /&gt;   // do something&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Could you imagine that I once worked for a company where the senior developers did not know about Iterators? So instead of&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;code style="color: Blue;"&gt;for (Iterator it = myStuff.iterator(); it.hasNext();) {&lt;br /&gt;   Object item = it.next();&lt;br /&gt;   // do something with the item&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;they had&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;code style="color: Blue;"&gt;for (int i = 0; i &amp;lt; myStuff.size(); i++) {&lt;br /&gt;   Object item = myStuff.get(i);&lt;br /&gt;   // do something with the item&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;and on top of that myStuff was a &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Vector.html"&gt;&lt;code&gt;Vector&lt;/code&gt;&lt;/a&gt;, which is synchronized. Very sloooow code!&lt;/p&gt;&lt;p&gt;Nevertheless my point is: &lt;span style="font-weight: bold;"&gt;Know your collections!&lt;/span&gt;&lt;/p&gt;&lt;p&gt;Now back to the topic of improving the Map iteration. Well, it really depends what we need to do at each step of our iteration.&lt;/p&gt;&lt;p&gt;If you need to iterate over the keys of the Map do this&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;code style="color: Blue;"&gt;for (Iterator it = myMap.&lt;span style="color:Red;"&gt;keySet()&lt;/span&gt;.iterator(); it.hasNext();) {&lt;br /&gt;   Object key = it.next();&lt;br /&gt;   // do something with the key&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;And if you need to iterate over the values of the Map do this&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;code style="color: Blue"&gt;for (Iterator it = myMap.&lt;span style="color:Red;"&gt;values()&lt;/span&gt;.iterator(); it.hasNext();) {&lt;br /&gt;   Object value = it.next();&lt;br /&gt;   // do something with the value&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;But what if we need both the key and the value? The usual approach and very bad approach is to get the set of keys, iterate over them and get the value for each key.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;code style="color: Blue"&gt;for (Iterator it = myMap.&lt;span style="color:Red;"&gt;keySet()&lt;/span&gt;.iterator(); it.hasNext();) {&lt;br /&gt;   Object key = it.next();&lt;br /&gt;   Object value = &lt;span style="color:Red;"&gt;myMap.get(key)&lt;/span&gt;;&lt;br /&gt;   // do something with the key and the value&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;What is wrong about this? Nothing! You can do it this way and it's perfectly fine. It is just very inefficient as at each iteration a map needs to look up the value for a given key. It is better to iterate over map entries. There is a special interface &lt;a href="http://java.sun.com/j2se/1.5.0/docs/api/java/util/Map.Entry.html"&gt;&lt;code&gt;Map.Entry&lt;/code&gt;&lt;/a&gt; that can be used to retrieve the key and the value of each entry in the map. So the previous example can be transformed into&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;code style="color: Blue;"&gt;for (Iterator it = myMap.&lt;span style="color:Red;"&gt;entrySet()&lt;/span&gt;.iterator(); it.hasNext();) {&lt;br /&gt;   &lt;span style="color:Red;"&gt;Map.Entry entry = (Map.Entry) it.next();&lt;/span&gt;&lt;br /&gt;   Object key = &lt;span style="color:Red;"&gt;entry.getKey();&lt;/span&gt;&lt;br /&gt;   Object value = &lt;span style="color:Red;"&gt;entry.getValue();&lt;/span&gt;&lt;br /&gt;   // do something with the key and the value&lt;br /&gt;}&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;Don't forget to change &lt;code&gt;myMap.get(key)&lt;/code&gt; to &lt;code&gt;entry.getValue()&lt;/code&gt;, otherwise you are not gaining anything from this modification. I did this recently, I omitted to change it, even worse - I changed it to &lt;code&gt;myMap.get(entry.getValue())&lt;/code&gt;. As a result the map was not finding anything... Luckily, we had tests around the class I modified and my stupid mistake was caught early.&lt;/p&gt;&lt;p&gt;Have the tests ready before making changes! Even experienced people make mistakes.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115545818898648347?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115545818898648347/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115545818898648347' title='10 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115545818898648347'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115545818898648347'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/08/improved-map-iteration_13.html' title='Improved Map Iteration'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>10</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115539814277420673</id><published>2006-08-13T01:27:00.000+10:00</published><updated>2006-08-13T01:55:42.796+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ajax'/><title type='text'>Server Polling - Reverse AJAX</title><content type='html'>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/23073412_af016f0917_t.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/200/23073412_af016f0917_t.jpg" alt="" border="0" /&gt;&lt;/a&gt; I am starting to feel a bit old or old-school. I know the concepts of AJAX but never had enough time (or project) to get my hands dirty doing AJAX. So I decided to make time and learn AJAX by doing.&lt;/p&gt;&lt;p&gt;I joined the &lt;a href="http://www.javapassion.com/ajaxcodecamp/"&gt;10-Week Free AJAX Programming (with Passion!)&lt;/a&gt; online course organized by &lt;a href="http://www.javapassion.com/SangSchedule.html#Bio"&gt;Sang Shin&lt;/a&gt; from Sun Microsystems. This course is in its second week now and the homework was:&lt;/p&gt;&lt;span style="font-style: italic;"&gt;"... to write one or two paragraphs describing an "interesting" AJAX related technology/feature you find while you are playing with the online demos or while reading AJAX articles on the net"&lt;/span&gt;&lt;br /&gt;&lt;p&gt;I though that it would be good to share my point of view with you. So, here I go.&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold;"&gt;Title:&lt;/span&gt; Server Polling - Reverse Ajax)&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;URL:&lt;/span&gt; &lt;a href="http://ajaxian.com/archives/reverse-ajax-with-dwr"&gt;http://ajaxian.com/archives/reverse-ajax-with-dwr&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Keeping the displayed information up-to-date was always difficult in web world. Before AJAX, one had to use JavaScript or &lt;a href="http://en.wikipedia.org/wiki/Meta_refresh"&gt;META Refresh tag&lt;/a&gt; to get the page refreshed. This was quite annoying from the user experience point of view. However it was not as annoying as something that I experienced few days ago on one of the banks website (a bank in Australia). I was filling out the form and there were couple of select boxes on the page. I selected an option in the select box and moved onto next field just to realize that as I was typing, the page has been reloaded and all data entered past that select-box was gone and had to be re-typed again. Very, very annoying - and it's AJAX age already!&lt;br /&gt;&lt;/p&gt;&lt;p&gt;Server polling, in my humble opinion, is a great feature of AJAX. There is no need to refresh the whole page to obtain the required information. With AJAX, it is possible to:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;update the forms with information as the user moves through the form (e.g. country - state - city)&lt;/li&gt;&lt;li&gt;get the feedback about a long server-side or transport process (e.g. progress bar showing the percentage of the uploading file)&lt;/li&gt;&lt;li&gt;fake the push of the updated data from the server (think stock prices, weather, traffic info)&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;I am sure that I will come across more coolness when I start writing more and more Ajax code!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115539814277420673?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='related' href='http://ajaxian.com/archives/reverse-ajax-with-dwr' title='Server Polling - Reverse AJAX'/><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115539814277420673/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115539814277420673' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115539814277420673'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115539814277420673'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/08/server-polling-reverse-ajax.html' title='Server Polling - Reverse AJAX'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115521401843141604</id><published>2006-08-10T22:13:00.000+10:00</published><updated>2006-08-12T13:25:17.826+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><category scheme='http://www.blogger.com/atom/ns#' term='string'/><category scheme='http://www.blogger.com/atom/ns#' term='refactoring'/><title type='text'>Empty String</title><content type='html'>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/21079076_2a6546e869_s.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/320/21079076_2a6546e869_s.jpg" alt="" border="0" /&gt;&lt;/a&gt; How many times have you coded a check for &lt;span style="font-weight: bold;"&gt;String being null or empty&lt;/span&gt;? Countless times, right? I have. We use some ready-to-use classes from open source frameworks or we write our own StringUtils class. More or less they all implement the same thing and it always looks similar to the following code snippet:&lt;/p&gt;&lt;p&gt;&lt;code style="color:Blue;"&gt;String s = ...&lt;br /&gt;if (s == null || s.equals(""))...&lt;/code&gt;&lt;br /&gt;&lt;/p&gt;&lt;p&gt;or similar to the following, which trims leading and ending whitespaces&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;code style="color:Blue;"&gt;String s = ...&lt;br /&gt;if (s == null || s.trim().equals(""))...&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Of course you could also do this:&lt;/p&gt;&lt;p&gt;&lt;code style="color:Blue;"&gt;"".equals(s)&lt;/code&gt;&lt;/p&gt;&lt;p&gt;which is a case when you do not care if String &lt;span style="font-family:courier new;"&gt;s&lt;/span&gt; is null and you don't have to worry about NPE as if won't happen (&lt;span style="font-family:courier new;"&gt;""&lt;/span&gt; is never null, whereas &lt;span style="font-family:courier new;"&gt;s&lt;/span&gt; could be). But that's another story.&lt;/p&gt;&lt;p&gt;I have had "extra" warnings turned on in my IDE for couple of days. But today my IDE suprised me when it highlighted&lt;/p&gt;&lt;p&gt;&lt;code style="color:Blue"&gt;[1] &lt;span style="font-weight: bold;"&gt;s.equals("")&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;and suggested that I could optimize it by making it to&lt;/p&gt;&lt;p&gt;&lt;code style="color:Blue"&gt;[2] &lt;span style="font-weight: bold;"&gt;s.length() == 0&lt;/span&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;And guess what?! The IDE was right! I looked at the suggested code briefly, gave it a bit of thought and agreed that it would probably be faster. Method [1] creates a new instance of the String (an empty String, yes I know that all instances of &lt;span style="font-family:courier new;"&gt;""&lt;/span&gt; would be caught during compilation and optimized and that they all would refer to the same instance). Just to be on the safe side I looked at the source of the String class.&lt;/p&gt;&lt;p&gt;And here is what I found. The &lt;span style="font-weight: bold;font-family:courier new;" &gt;length()&lt;/span&gt; method returns and integer primitive, which is not calculated with each method call to length(). It is rather a member variable (or constant, as Strings are invariants) of String class that is calculated when new String instance is created. So this method would be super fast.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;code style="color:Blue"&gt;536   public int &lt;span style="font-weight: bold;"&gt;length&lt;/span&gt;()&lt;br /&gt;537   {&lt;br /&gt;538       return count;&lt;br /&gt;539   }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;On the other side, there is the &lt;span style="font-weight: bold;font-family:courier new;" &gt;equals()&lt;/span&gt; method, which is fast as well, but not as fast as length method. It has to do a check for class, class casting and comparison of count members (that's what length method returns).&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;pre&gt;&lt;code style="color: Blue;"&gt;684   public boolean &lt;span style="font-weight: bold;"&gt;equals&lt;/span&gt;(Object anObject)&lt;br /&gt;685   {&lt;br /&gt;686     if (! (anObject instanceof String))&lt;br /&gt;687       return false;&lt;br /&gt;688     String str2 = (String) anObject;&lt;br /&gt;689     if (count != str2.count)&lt;br /&gt;690       return false;&lt;br /&gt;691     if (value == str2.value &amp;&amp;amp; offset == str2.offset)&lt;br /&gt;692       return true;&lt;br /&gt;693     int i = count;&lt;br /&gt;694     int x = offset;&lt;br /&gt;695     int y = str2.offset;&lt;br /&gt;696     while (--i &gt;= 0)&lt;br /&gt;697       if (value[x++] != str2.value[y++])&lt;br /&gt;698         return false;&lt;br /&gt;699     return true;&lt;br /&gt;700   }&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And remember the few important points when it comes to Strings:&lt;br /&gt;&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Do not compare Strings with &lt;span style="font-family:courier new;"&gt;==&lt;/span&gt; operator.&lt;/span&gt; Unless you want to compare the object references. Use &lt;span style="font-family:courier new;"&gt;equals()&lt;/span&gt; method.&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Do not construct new instances like &lt;span style="font-family:courier new;"&gt;new String("abc")&lt;/span&gt;.&lt;/span&gt; Simple &lt;span style="font-family:courier new;"&gt;"abc"&lt;/span&gt; will do, unless you really mean that you need a new instance of String with same value. Read more about &lt;a href="http://hanuska.blogspot.com/2006/03/how-useful-is-stringstring-constructor.html"&gt;How useful is &lt;code&gt;String(String)&lt;/code&gt; constructor&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Do not concatenate Strings in loops using &lt;/span&gt;&lt;span style="font-weight: bold;font-family:courier new;" &gt;+&lt;/span&gt;&lt;span style="font-weight: bold;"&gt; operator.&lt;/span&gt; It's faster to use &lt;span style="font-weight: bold;font-family:courier new;" &gt;StringBuffer&lt;/span&gt; (or &lt;span style="font-weight: bold;font-family:courier new;" &gt;StringBuilder&lt;/span&gt;, which is in Tiger and is not synchronized)&lt;span style="font-family:courier new;"&gt; append()&lt;/span&gt; and then &lt;span style="font-family:courier new;"&gt;toString()&lt;/span&gt; methods instead. The plus (+) operator constructs new String object each time.&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;p&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115521401843141604?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115521401843141604/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115521401843141604' title='12 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115521401843141604'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115521401843141604'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/08/empty-string.html' title='Empty String'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>12</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115474752360644689</id><published>2006-08-05T12:18:00.000+10:00</published><updated>2006-12-31T13:51:27.840+11:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='java'/><title type='text'>Comments in Java Code</title><content type='html'>&lt;p&gt;We all use comments to describe the Java code. There are three types if comments in Java as demonstrated in this &lt;a href="http://java.sun.com/docs/books/tutorial/getStarted/application/comments.html"&gt;Java tutorial&lt;/a&gt; by SUN:&lt;/p&gt;&lt;p&gt;&lt;code style="color: Red;"&gt;// text&lt;/code&gt;&lt;/p&gt;&lt;p&gt;where the compiler ignores everything from &lt;code&gt;//&lt;/code&gt; to the end of the line&lt;/p&gt;&lt;p&gt;&lt;code style="color: Red;"&gt;/* text */&lt;/code&gt;&lt;/p&gt;&lt;p&gt;where the compiler ignores everything from &lt;code&gt;/*&lt;/code&gt; to &lt;code&gt;*/&lt;/code&gt; and&lt;/p&gt;&lt;p&gt;&lt;code style="color: Red;"&gt;/** documentation */&lt;/code&gt;&lt;/p&gt;&lt;p&gt;which is ignored by the compiler the same way as the previous comment type. This one is a special comment as this indicates a documentation comment. The JDK &lt;a href="http://java.sun.com/j2se/javadoc/index.jsp"&gt;javadoc&lt;/a&gt; tool uses doc comments when preparing automatically generated documentation.&lt;/p&gt;&lt;p&gt;I am not going to tell you how to use them. There are many articles and documentation written about that. We all know how to use them and most of us use them on a daily basis. Over time we can develop a stereotype. Mine looks like this:&lt;/p&gt;&lt;p&gt;&lt;code  style="color:Blue;"&gt;&lt;br /&gt;&lt;span style="color:Red;"&gt;/** first name */&lt;/span&gt;&lt;br /&gt;private String firstName;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:Red;"&gt;/** last name */&lt;/span&gt;&lt;br /&gt;private String lastName;&lt;br /&gt;&lt;br /&gt;&lt;span style="color:Red;"&gt;/**&lt;br /&gt; * Constructs and returns the full name&lt;br /&gt; * @return full name&lt;br /&gt; */&lt;/span&gt;&lt;br /&gt;public String getFullName() {&lt;br /&gt;  if (firstName == null) {&lt;br /&gt;    if (lastName == null) {&lt;br /&gt;      &lt;span style="color:Red;"&gt;// user does not have a name specified&lt;/span&gt;&lt;br /&gt;      return "[no name]";&lt;br /&gt;    }&lt;br /&gt;    else {&lt;br /&gt;      return lastName;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;  else {&lt;br /&gt;    if (lastName == null) {&lt;br /&gt;      return firstName;&lt;br /&gt;    }&lt;br /&gt;    else {&lt;br /&gt;      &lt;span style="color:Red;"&gt;// construct full name from first and last name&lt;/span&gt;&lt;br /&gt;      return firstName + " " + lastName;&lt;br /&gt;    }&lt;br /&gt;  }&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;As you can see, I use doc comments to describe the meaning and function of my class members. I also like to use line comments, rather than block comments. Even if my comment spans multiple lines I prefer to use &lt;code&gt;//&lt;/code&gt; comments. It's due to my IDE settings. When I press Ctrl+/ it un-/comments the selected lines. It's very neat feature and I use it a lot.&lt;/p&gt;&lt;p&gt;Recently, I was doing some code modifications and I wanted to re-visit some code later. I decide to break the code by putting a comment in the middle if it, so it would not compile and I would be forced to come back to it.&lt;/p&gt;&lt;p&gt;I did somethig like this:&lt;/p&gt;&lt;p&gt;&lt;code  style="color:Blue;"&gt;&lt;br /&gt;myObject.getAnother()&lt;span style="color:Red;"&gt;/* change to ID */&lt;/span&gt;.getName();&lt;/code&gt;&lt;/p&gt;&lt;p&gt;To my surprise the code did not break. Even when I changed it to&lt;/p&gt;&lt;p&gt;&lt;code  style="color:Blue;"&gt;&lt;br /&gt;myObject.getAnother().&lt;span style="color:Red;"&gt;/* change to ID */&lt;/span&gt;getName();&lt;/code&gt;&lt;/p&gt;&lt;p&gt;Obviously, when I did this&lt;/p&gt;&lt;p&gt;&lt;code  style="color:Blue;"&gt;&lt;br /&gt;myObject.getAnother().ge&lt;span style="color:Red;"&gt;/* change to ID */&lt;/span&gt;tName();&lt;/code&gt;&lt;/p&gt;&lt;p&gt;the code broke. At the end I made it to break in a nice way, anyway&lt;/p&gt;&lt;p&gt;&lt;code  style="color:Blue;"&gt;&lt;br /&gt;myObject.getAnother().&lt;span style="color:Red;"&gt;/* change to ID */&lt;/span&gt;.getName();&lt;/code&gt;&lt;/p&gt;&lt;p&gt;(notice an extra dot)&lt;/p&gt;&lt;p&gt;All this made me thinking. Where are all the valid spots for the comments. After I read the definition for Java comments I understood why it worked, but I simply find it puzzling. Of course, we do not put comments in places like this, but the language allows us to.&lt;/p&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;I am not sure if there is any value in this lesson learnt. It would certainly make a good exam question though. I can see it now: &lt;span style="font-style: italic;"&gt;"Will the following code compile?"&lt;/span&gt; ...&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115474752360644689?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115474752360644689/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115474752360644689' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115474752360644689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115474752360644689'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/08/comments-in-java-code.html' title='Comments in Java Code'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115354438657396874</id><published>2006-07-22T14:46:00.000+10:00</published><updated>2006-07-22T15:01:02.513+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>Debug This!</title><content type='html'>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/P7114260_resize.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/200/P7114260_resize.jpg" alt="" border="0" /&gt;&lt;/a&gt;Whilst in Korea, my cousin Ladislav Babinec took this shot. Both, he and I have a bit of electrical engineering background (he works for a &lt;a href="http://www.t-com.sk/En/"&gt;T-Com&lt;/a&gt; originally &lt;a href="http://www.telecom.sk/En"&gt;Slovak Telecom&lt;/a&gt;). So we were amazed how an electrician would go about fixing this &lt;span style="font-style: italic;"&gt;mess&lt;/span&gt;. Or maybe they hire only the elecricians with special puzzle solving skills. After this photo had been taken I noticed similar electric poles in many places throughout Seoul. Simply amazing! I wonder what tools do those electricians use for &lt;span style="font-style: italic;"&gt;debugging&lt;/span&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115354438657396874?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115354438657396874/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115354438657396874' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115354438657396874'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115354438657396874'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/07/debug-this.html' title='Debug This!'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115354078518293741</id><published>2006-07-22T13:29:00.000+10:00</published><updated>2006-07-22T14:01:49.890+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='design'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>Good Design</title><content type='html'>&lt;p&gt;I am back from the wonderful trip to South Korea, where my wife comes from. We spent some time sightseeing Seoul and some time meeting with Miae's relatives. I am already looking forward the next time we visit Korea and will travel around the country.&lt;/p&gt;&lt;p&gt;Before one of the meetings we had,  I had to go to a restroom. It was in a very luxurious 5-star hotel. As I was sitting there and doing my business I noticed a little white box mounted on the wall. This little device had a display and many buttons. As I can read Korean script (Hangul), but have no idea what I read, I had absolutely no clue what this magic white-box is for. Naturally, I knew there was a connection with the &lt;span style="font-style: italic;"&gt;human waste disposal unit&lt;/span&gt; I was sitting on.&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/DSCF7617_resize.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/320/DSCF7617_resize.jpg" alt="" border="0" /&gt;&lt;/a&gt;What was even worse was the fact the the most common button - FLUSH - was nowhere to be found. I checked the usual spots around the toilet, but I found absolutely nothing. So I decided (as a citizen of a developed country and an educated man) that I have to have a crack on this thing and must be able to flush using basic logic and common sense.&lt;/p&gt;&lt;p&gt;Koreans are probably laughing at me right now, but I failed miserably. I pressed few &lt;span style="font-style: italic;"&gt;this-must-work&lt;/span&gt; buttons, but could not make that damn thing to flush. So I left with shame, leaving a surprise present for the lucky person who would come after me. Luckily, no one was waiting so I got away with it without too much embarrassment.&lt;/p&gt;&lt;p&gt;This whole story reminds me of an excellent book I read long time ago. &lt;a href="http://www.amazon.com/gp/product/0465067107/sr=8-1/qid=1153538817/ref=pd_bbs_1/104-0436100-4361544?ie=UTF8"&gt;The design of Everyday Things&lt;/a&gt; by Donald A. Norman talks about the good and bad design of things we use everyday. He says that if things are designed well, no manuals, no labels, no description text is necessary. You simply grab the thing and use it in a right way. How many times you tried to push the door that was meant to be pulled just because the door handle was easier to grab and push? How many times you pushed the wrong light switch because the switches were not in logical order?&lt;/p&gt;&lt;p&gt;Well, I don't know if it was me this time or a bad design. Why do we need so many buttons for the toilet anyway?&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115354078518293741?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115354078518293741/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115354078518293741' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115354078518293741'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115354078518293741'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/07/good-design.html' title='Good Design'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115255152004836848</id><published>2006-07-11T03:05:00.000+10:00</published><updated>2006-07-11T03:12:00.070+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>Korean Coca-Cola Zero</title><content type='html'>&lt;p&gt;My "coffee" - I am happy that I can find what I need on my trip in Korea :-)&lt;/p&gt;&lt;p&gt;&lt;span style="font-weight: bold;"&gt;Kkokka-Kkolla Jero&lt;/span&gt;&lt;br /&gt;&lt;/p&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/DSCF7184_resize.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/400/DSCF7184_resize.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115255152004836848?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115255152004836848/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115255152004836848' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115255152004836848'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115255152004836848'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/07/korean-coca-cola-zero.html' title='Korean Coca-Cola Zero'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115254876978918905</id><published>2006-07-11T02:01:00.000+10:00</published><updated>2006-07-11T03:05:01.896+10:00</updated><title type='text'>What am I up to these days?</title><content type='html'>&lt;p&gt;You may have been wondering why I am not blogging as frequently as I did before. Well, I am on vacation in Seoul, South Korea.&lt;/p&gt;&lt;p&gt;As it usually happens there are more things to see than there is time. And since July is the month with the highest rainfall, I feel lucky to enjoy so many days with very little rain so far.&lt;/p&gt;&lt;p&gt;The following are:&lt;br /&gt;&lt;/p&gt;&lt;ol&gt;&lt;li&gt;Bell at the entrance to &lt;span style="font-weight: bold;"&gt;Bongwonsa&lt;/span&gt; - the largest of the temples, next to Inwangsan - Seoul's most famous shamanist shrine,&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Resting pavilon in the &lt;span style="font-weight: bold;"&gt;Korean Folk Village&lt;/span&gt;,&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Hyowon Bell&lt;/span&gt; at the &lt;span style="font-weight: bold;"&gt;Hwaseong&lt;/span&gt; (Suwon Fortress) - UNESCO World Cultural Heritage,&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Gyengbokgung&lt;/span&gt; - Palace of Shining Hapiness, the Primary Palace of Joseon Dynasty,&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;Geunjeongjeon&lt;/span&gt; - the greatest building at Gyengbokgung where ceremonies of the state took place.&lt;/li&gt;&lt;/ol&gt;&lt;p&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/DSCF7201_resize.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/400/DSCF7201_resize.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/DSCF7356_resize.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/400/DSCF7356_resize.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/DSCF7498_resize.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/400/DSCF7498_resize.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/DSCF7547_resize.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/400/DSCF7547_resize.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/DSCF7578_resize.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/400/DSCF7578_resize.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115254876978918905?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115254876978918905/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115254876978918905' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115254876978918905'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115254876978918905'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/07/what-am-i-up-to-these-days.html' title='What am I up to these days?'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115202165108978892</id><published>2006-07-04T23:50:00.000+10:00</published><updated>2006-07-05T00:05:21.680+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>Southpark - how would you look like if you were there?</title><content type='html'>&lt;p&gt;This is Miae and me in Southpark - well, the way we see ourselves.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;This image was generated using the &lt;a href="http://www.sp-studio.de/"&gt;Planearium&lt;/a&gt; and paintbrush.&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/Miae_and_Dushan_in_Southpark.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/320/Miae_and_Dushan_in_Southpark.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115202165108978892?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115202165108978892/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115202165108978892' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115202165108978892'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115202165108978892'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/07/southpark-how-would-you-look-like-if.html' title='Southpark - how would you look like if you were there?'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115140099934704427</id><published>2006-06-27T18:49:00.000+10:00</published><updated>2006-06-27T23:01:20.613+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pair programming'/><category scheme='http://www.blogger.com/atom/ns#' term='xp'/><category scheme='http://www.blogger.com/atom/ns#' term='book'/><title type='text'>Pair Programming Habits</title><content type='html'>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/pair_programming_illuminated.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 110px; height: 139px;" src="http://photos1.blogger.com/blogger/2606/2479/320/pair_programming_illuminated.jpg" alt="" border="0" /&gt;&lt;/a&gt;I finished reading &lt;a href="http://www.amazon.com/gp/product/0201745763/qid=1148290311/sr=2-1/ref=pd_bbs_b_2_1/104-0436100-4361544?s=books&amp;v=glance&amp;amp;n=283155"&gt;Pair Programming Illuminated&lt;/a&gt;, a book written by Laurie Williams and Robert Kessler. I talked about this book in my previous blog: "&lt;a href="http://hanuska.blogspot.com/2006/05/seven-myths-of-pair-programming.html"&gt;The Seven Myths of Pair Programming&lt;/a&gt;". I really enjoyed reading this book. It's time to put it back the shelf, so other developers in our office can get their hands on it, but I am sure I will come back to is sometimes. I want to talk a bit about one of the chapter at the end of this book.&lt;/p&gt;&lt;h3&gt;Seven Habits of Effective Pair Programming&lt;/h3&gt;&lt;h4&gt;Habit 1: Take Breaks&lt;/h4&gt;&lt;p&gt;This was one of the things that we identified early on. Pair programming is a very intensive activity. We worked in pairs whole day. And then at the end of the day, exhausted, we were still in the office catching up with the pile of e-mails and other administrative stuff. Take breaks on regular basis. Have a coffee, tea, talk to other developers, stretch, do whatever - simply, have a break!&lt;/p&gt;&lt;h4&gt;Habit 2: Practice Humility&lt;/h4&gt;&lt;p&gt;One of my favorite quotes that I use on daily basis: "Pair programming makes me feel stupid everyday. I love it!"&lt;br /&gt;&lt;/p&gt;&lt;h4&gt;Habit 3: Be Confident / Be Receptive&lt;/h4&gt;&lt;p&gt;Do not be afraid to appear dumb. Nobody expects you to know everything. You do not expect the others to know the answers to all your questions, do you? And remember, this is a teamwork, not a competition.&lt;/p&gt;&lt;h4&gt;Habit 4: Communicate&lt;/h4&gt;&lt;p&gt;This is very important. Today I had an encounter with one of our staff. He is not usually exposed to pair programming that we practice in our team. He came over to my computer and typed commands rapidly on the command line. No words said. I could not follow him. I was not experienced enough in that particular area and wanted to learn from him, so I asked him if he could comment what he was doing. I felt stupid again... but hey, I learnt something!&lt;/p&gt;&lt;h4&gt;Habit 5: Listen&lt;/h4&gt;&lt;p&gt;This is important as well. We all dive deeply into our thought when we type away our code. Sometimes I found myself not really listening to the navigator. When I finished, I had to ask what he said and reiterate thought his thought.&lt;/p&gt;&lt;p&gt;Another case is when you listen but assume you know what he or she is going to say. Do not assume. Listen! If he or she wants to say something, there is probably a good reason for it.&lt;/p&gt;&lt;h4&gt;Habit 6: Be a Team Player&lt;/h4&gt;&lt;p&gt;No much to be said here. Just be part of what is happening. Be actively involved in the process, whether it is coding or just thinking as a navigator. You need to be able to understand what is going on at any moment. If you don't, ask!&lt;/p&gt;&lt;h4&gt;Habit 7: Hone the Balance between Compromise and Standing Firm&lt;/h4&gt;&lt;p&gt;It's hard to find balance if you try to go separate ways. Always think that this is a teamwork and the way the project should be heading.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115140099934704427?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115140099934704427/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115140099934704427' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115140099934704427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115140099934704427'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/06/pair-programming-habits.html' title='Pair Programming Habits'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115131899824426689</id><published>2006-06-26T20:46:00.000+10:00</published><updated>2006-06-26T20:49:58.256+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='ide'/><category scheme='http://www.blogger.com/atom/ns#' term='plugin'/><category scheme='http://www.blogger.com/atom/ns#' term='google'/><title type='text'>GWT Studio Plugin for IntelliJ IDEA</title><content type='html'>&lt;p&gt;Alex Tkachman of Jetbrains announced on Friday that he had developed a plugin that adds support for Google Web Toolkit (GWT) to IntelliJ IDEA.&lt;/p&gt;&lt;p&gt;&lt;a href="http://www.jetbrains.net/confluence/display/IDEADEV/GWT+Studio+plugin"&gt;More information and a watchable demo&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115131899824426689?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115131899824426689/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115131899824426689' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115131899824426689'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115131899824426689'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/06/gwt-studio-plugin-for-intellij-idea.html' title='GWT Studio Plugin for IntelliJ IDEA'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115114129022818244</id><published>2006-06-24T19:18:00.000+10:00</published><updated>2006-06-24T19:31:19.626+10:00</updated><title type='text'>Cold Foggy Morning in Winter Sydney</title><content type='html'>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/DSCF6862bwsm.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: left; cursor: pointer; width: 704px; height: 530px;" src="http://photos1.blogger.com/blogger/2606/2479/1600/DSCF6862bwsm.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115114129022818244?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115114129022818244/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115114129022818244' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115114129022818244'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115114129022818244'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/06/cold-foggy-morning-in-winter-sydney.html' title='Cold Foggy Morning in Winter Sydney'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115062052140749714</id><published>2006-06-18T18:43:00.000+10:00</published><updated>2006-06-18T18:48:41.423+10:00</updated><title type='text'>Programming for mobile devices</title><content type='html'>&lt;p&gt;If you are into programming for mobile devices and have not really dived into it yet, here is a usefull article that talks about &lt;a href="http://today.java.net/pub/a/today/2006/04/25/writing-cool-games-for-mobile-devices.html"&gt;writing cool games for cellular devices&lt;/a&gt;. I did not spent much time on it, but it seems like a very good tutorial with a complete example that might be useful for me one day - hence this blog post.&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115062052140749714?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115062052140749714/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115062052140749714' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115062052140749714'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115062052140749714'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/06/programming-for-mobile-devices.html' title='Programming for mobile devices'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115044763357209265</id><published>2006-06-16T18:43:00.000+10:00</published><updated>2006-06-16T19:01:52.730+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pair programming'/><category scheme='http://www.blogger.com/atom/ns#' term='xp'/><category scheme='http://www.blogger.com/atom/ns#' term='best practice'/><title type='text'>Pair Programming and Office Environment</title><content type='html'>&lt;p style="text-align: justify;"&gt;Everyday I come to the office and I see people working. We all work in different ways. Sometimes we work by ourselves, sometimes we pair up to work together on a card we pick from the wall (card = task from the story board). These two ways of working are very different and I would like to share my thoughts on them with you.&lt;/p&gt;&lt;h2&gt;Caves&lt;/h2&gt;&lt;p style="text-align: justify;"&gt;People need privacy. They need to take or make phone calls or do some other things without disturbing others in the office. They also need to have a "home base", where they can keep their belongings. Such places could be small offices or cubicles.&lt;/p&gt;&lt;p style="text-align: justify;"&gt;Caves are also great for pairs whose task is to investigate something that none of the developers in that pair have experience with. This way some new things can be explored in a much more efficient way and different approaches can produce various results. These can be later discussed and a common solutions can be found. If the pair worked on one PC, the productivity would be only slightly better than of one developer working alone.&lt;/p&gt;&lt;h2&gt;Commons&lt;/h2&gt;&lt;p style="text-align: justify;"&gt;When it comes to pairing, people typically use their "personal spaces" or designated spaces, such as pairing desks or pairing rooms. There are two roles in each pair. The driver is the person who is in control of the keyboard and mouse at that moment. The other person is usually called the navigator.&lt;/p&gt;&lt;p style="text-align: justify;"&gt;In the case of the personal spaces, each desk must not limit the access to the PC. What I mean by that, is that the desk is best to be straight. Corner desks do not allow the developers to sit next to each other. Then it looks like the navigator is breathing down the driver’s neck and has very limited visibility of the screen. So, the "cave" is unsuitable for this task.&lt;/p&gt;&lt;p style="text-align: justify;"&gt;There are several variations of the pairing desk set-up. Let's talk about them in more detail.&lt;/p&gt;&lt;h3&gt;One PC, one screen, one mouse, one keyboard&lt;/h3&gt;&lt;p style="text-align: justify;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/d1111.0.gif"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/320/d1111.0.gif" alt="" border="0" /&gt;&lt;/a&gt;In this configuration, there is only one screen, so the settings must be so the navigator has as good visibility of the screen as the driver. Otherwise the navigator can not contribute much and the productivity of the pair is impaired. The navigator has no active control of what is happening. The only way the navigator can influence the process is by telling or suggesting to the driver. The limitation of having just one keyboard and mouse typically results in "switching" roles. When the navigator decides to drive, the control is passed onto him/her obviously by handing of the keyboard and mouse. Therefore everyone in the office can see who has what role in each pair at that given moment.&lt;/p&gt;&lt;p style="text-align: justify;"&gt;The usual way the developers drive is that they share a larger space in front of the screen. Ideally the developers should sit side by side and share the same (50%) of the screen space. This can only be achieved by having large and/or widescreen monitors (21 inch or larger). See the images below to see how large screen can work for a pair.&lt;/p&gt;&lt;p style="text-align: justify;"&gt;For the smaller screens the percentage the driver occupies is related to the size of the screen. For the 19 inch monitors it is approximately 60%. As the roles switch the developers shift to take or give space as shown on the images below.&lt;/p&gt;&lt;p style="text-align: justify;"&gt;&lt;table border="0" cellpadding="0" cellspacing="0"&gt;&lt;tbody&gt;&lt;tr&gt;&lt;td&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/d1111a.gif"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/320/d1111a.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/d1111b.gif"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/320/d1111b.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt;&lt;/p&gt;&lt;h3&gt;One PC, one screen, one keyboard, two mice&lt;br /&gt;&lt;/h3&gt;&lt;p style="text-align: justify;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/d1121a.gif"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/320/d1121a.gif" alt="" border="0" /&gt;&lt;/a&gt;A step up is to have two mice. Having USB mice is great. Just plug one more mouse into your PC and voilà. You are good to go. The OS should recognize both mice and you should be able to use them. Unfortunately, there is only one mouse pointer on the screen, so you have to fight for it. (Well, at least I did not find a good software that would allow you to have two separate mouse pointers.&lt;/p&gt;&lt;p style="text-align: justify;"&gt;Having two mice has a significant benefit. The navigator does not need to be told: "DON'T TOUCH MY SCREEN" when pointing at something on the screen. A mouse can be used for that. Moreover, the mouse is a powerful tool these days. There is so much you can get done with just a click.&lt;/p&gt;&lt;p style="text-align: justify;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/d1121b.gif"&gt;&lt;img style="margin: 0pt 0pt 10px 10px; float: right; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/320/d1121b.gif" alt="" border="0" /&gt;&lt;/a&gt;Alright, so we have two mice, how do we switch roles. It's almost the same as before. The keyboard gets passed around. This setup usually results in the navigator sitting on the left and having the control over the spare mouse. The driver typically sits on the right having the control over the keyboard and the mouse. When the roles changes, as displayed below, the driver who becomes the navigator (on the right) loses the control and because there is no extra mouse on the right the navigator is quite passive (same as in the configuration with one keyboard and one mouse only).&lt;/p&gt;&lt;p style="text-align: justify;"&gt;The only solution to the right-side navigator's passivity would be an extra mouse on the right. It can work, I have never tried it and personally, it's just too many rodents on one's desk.&lt;/p&gt;&lt;h3&gt;One PC, one screen, two keyboards, two mice&lt;/h3&gt;&lt;p style="text-align: justify;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/d1122.gif"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/320/d1122.gif" alt="" border="0" /&gt;&lt;/a&gt;This is another step up for a better working configuration. In this case another keyboard is added to the PC. Each developer has his/her keyboard and mouse combo. In this way the developers can very effectively switch roles, almost instantly a navigator can jump in and drive for a few moments and then give the control back to the driver.&lt;/p&gt;&lt;p style="text-align: justify;"&gt;If your company can not afford to have spare sets of input devices, just bring your own to the pairing desk. All of us have the PCs, the keyboards and the mice, right? So, just unplug them from your PC and bring them to the pairing PC. Ideally, you would not have to do this. There should be some spare sets. The best results are if these are wireless as they tend to clutter the desk less and are easily portable. The only problem that can arise is that their frequencies may start to interfere, so wired ones might prove the best.&lt;/p&gt;&lt;h3&gt;One PC, two screens, two keyboards, two mice&lt;/h3&gt;&lt;p style="text-align: justify;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/d1222.gif"&gt;&lt;img style="margin: 0px 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/400/d1222.gif" alt="" border="0" /&gt;&lt;/a&gt;This is an ideal configuration and if you have it, you can call yourself lucky. There are not many companies that I know of that would provide their developer with such luxury. In our company we have several pairing rooms equipped with fast PCs and dual 21 inch screens with two sets of keyboards and mice.&lt;/p&gt;&lt;p style="text-align: justify;"&gt;This configuration is not only ideal from a driving point of view, but as a navigator you have a full view of the screen. Sometimes you might feel that when you are the navigator the machine is doing your work (that is if you ignore that dude on your side, but be nice to him as he might feel the same when you drive.)&lt;/p&gt;&lt;p style="text-align: justify;"&gt;Alternatively, the real estate of the two large screens can be used more efficiently by splitting the desktop. This can be done by stretching the desktop the way the one half is of one screen and the second half is on the other screen. This is useful most typically in cases when you need one window with source code and another window for testing the application (web browser for web applications.)&lt;/p&gt;&lt;h3&gt;Laptops and pair programming&lt;/h3&gt;&lt;p style="text-align: justify;"&gt;Laptops are nice little useful things. I love them. But they are not ideal for pair programming. Well, unless some special setup is done.&lt;/p&gt;&lt;p style="text-align: justify;"&gt;Read more about &lt;a href="http://hanuska.blogspot.com/2006/06/why-laptops-are-no-good-for-pair.html"&gt;why the laptops are no good for pair programming&lt;/a&gt;.&lt;/p&gt;&lt;p style="text-align: justify;"&gt;What can we do? How can we be pair programming and using laptops at the same time?&lt;/p&gt;&lt;p style="text-align: justify;"&gt;The answer is not that difficult. All you need to accommodate the second developer is a screen, a keyboard and a mouse. Have you heard about USB? Get a USB keyboard and a mouse, and you are set. Well almost. The second developer needs to see as well. Give him/her a screen. Laptops have video outputs these days. It should be no problem to plug in additional monitor. The only &lt;/p&gt;&lt;p style="text-align: justify;"&gt;trouble might be setting up the resolution so it fits the laptop's screen as well as additional monitor's.&lt;/p&gt;&lt;p style="text-align: justify;"&gt;Alternatively you could configure the desktop to be stretched onto the second screen and this way you can use more real-estate as long as you maintain good visibility of both screens for both of you.&lt;/p&gt;&lt;h2&gt;Office layout&lt;/h2&gt;&lt;p style="text-align: justify;"&gt;So far, we have talked about the desk configuration. But what about how the desks should be organized in the office?&lt;/p&gt;&lt;p style="text-align: justify;"&gt;There are two factors to consider. Noise and communication. The communication is important not only within the pair, but also inter-pair. It is most beneficial if you can communicate quickly and when needed. The layout of the desks in the office should allow you to see and talk to other pairs easily. The layout documented in many XP books and articles describes the setting of six desks as on the picture below.&lt;/p&gt;&lt;p style="text-align: justify;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/office-h.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/400/office-h.gif" alt="" border="0" /&gt;&lt;/a&gt;If you have enough space in the center of the room, this setup can work the best. The pairs can see each other and can talk to each other without shouting across the room. They also have a semi-private space where the pairs can work without generating too much noise disturbing the others.&lt;/p&gt;&lt;p style="text-align: justify;"&gt;These desks should be big enough to easily accommodate both developers, equipped with fast PCs and two sets of keyboards and mice. These should belong to the common area, they should not be personal caves of anyone.&lt;/p&gt;&lt;p style="text-align: justify;"&gt;We do not have this setup. We have pairing rooms that are well equipped, but they are rooms. And as such they isolate the pair from other pairs. The downside of it is that the developers very rarely communicate between pairs outside the meetings (formal or informal) when outside of the pairing rooms. Not all developers get to use these rooms. Simply, it's just too many of us and too few rooms. So we use our personal spaces for pairing as well. Neither our desks are located in the middle of room. The are lined-up along the walls and windows around the office. And so on some occasions there are big gaps between us and we have to walk across the room to talk to our peers.&lt;/p&gt;&lt;p style="text-align: justify;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/desks.gif"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/400/desks.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p style="text-align: justify;"&gt;No matter what the layout of the desks in your office is, try to respect the solo developers who require a quiet atmosphere for their thought flow. Pairs generate more office noise but can also effectively block out the noise generated by others. Solo programmers can not (unless they have earplugs and some loud music). Ideally, the pairs could be in a separate room from the personal spaces where we all work alone.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115044763357209265?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115044763357209265/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115044763357209265' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115044763357209265'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115044763357209265'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/06/pair-programming-and-office.html' title='Pair Programming and Office Environment'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115038695540570393</id><published>2006-06-16T01:43:00.000+10:00</published><updated>2006-06-16T01:55:55.440+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pair programming'/><category scheme='http://www.blogger.com/atom/ns#' term='xp'/><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>Pair Programming just got better</title><content type='html'>&lt;p&gt;Today I got a new monitor. I had a 20" widescreen monitor before and the things just got better. After I had unwrapped and assembled my new 24" monitor, I sat in front of it and felt like in the cinema. The old 20" monitor (on the left) now looks like a dwarf...&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/new-monitor.jpg"&gt;&lt;img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/320/new-monitor.jpg" alt="" border="0" /&gt;&lt;/a&gt;&lt;/p&gt;&lt;p&gt;Pair Programming is a lot easier on a big screen.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115038695540570393?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115038695540570393/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115038695540570393' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115038695540570393'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115038695540570393'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/06/pair-programming-just-got-better.html' title='Pair Programming just got better'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115021527195798536</id><published>2006-06-14T01:56:00.000+10:00</published><updated>2006-06-14T02:14:33.113+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='pair programming'/><category scheme='http://www.blogger.com/atom/ns#' term='xp'/><title type='text'>Why laptops are no good for pair programming</title><content type='html'>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/laptop.0.jpg"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 87px; height: 68px;" src="http://photos1.blogger.com/blogger/2606/2479/200/laptop.0.jpg" alt="" border="0" /&gt;&lt;/a&gt;Laptops are great! There are small powerful gadgets that you get to drag to anywhere you want and use them as they come. I love laptops! Laptop is like your super-sized personal organizer. I use my laptop for all my office-type-of-work. By that I mean e-mailing, writing documents, blogging, Internet whatevering (substitute with browsing, banking, surfing, etc.)&lt;/p&gt;&lt;p&gt;They are great, if you are using them by yourself. But when it comes to pairing, they are no good. And I tell you why.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;Laptops have usually smaller screens.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;The navigator can not see as clearly what the driver sees (if anything at all, depending on the screen resolution).&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;The control is harder to pass around.&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;When the control is passed to the other person, that usually means that the whole laptop is handed over.&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Laptops are less powerful then full-blown desktop PCs&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;One could argue that it is not true, that laptops can be as powerful as desktops. Yes but at what price? And all we developers need is computing power to run the compilations as fast as we can.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Laptops are usually more expensive&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;You can get more on desktop for the same price. No need to say more.&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;On a bright side, the laptops are tax deductible, and you can salary-sacrifice it in one year. Every year. Well, in Aussieland we can. It takes three years for ordinary PCs to be written off.&lt;/p&gt; &lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;li&gt;&lt;p&gt;Laptops are harder to upgrade&lt;/p&gt;&lt;ul&gt;&lt;li&gt;&lt;p&gt;They are simply less pluggable than desktop PCs. Therefore they age quicker.&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;p&gt;Would I choose to have a laptop? Definitely! But not for pair programming. For that, I'd choose to have a nice and fast desktop PC.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115021527195798536?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115021527195798536/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115021527195798536' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115021527195798536'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115021527195798536'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/06/why-laptops-are-no-good-for-pair.html' title='Why laptops are no good for pair programming'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115019459416172869</id><published>2006-06-13T20:25:00.000+10:00</published><updated>2006-06-13T20:29:54.173+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='funny'/><title type='text'>Windows Noises</title><content type='html'>&lt;p&gt;I was looking for some cool sound effects for my new phone and I came across this webpage that features a soundtrack that was entirely made by Sound Recorder (sndrec32.exe) that comes with MS Windows.&lt;/p&gt;&lt;p&gt;I was impressed! Simple and cool! &lt;a href="http://www.geocities.com/clownstaples"&gt;Check it out!&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115019459416172869?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115019459416172869/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115019459416172869' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115019459416172869'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115019459416172869'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/06/windows-noises.html' title='Windows Noises'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-23939980.post-115006860136303428</id><published>2006-06-12T09:05:00.000+10:00</published><updated>2006-06-12T09:30:01.380+10:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='best practice'/><title type='text'>Code Conventions</title><content type='html'>&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/j0383528.gif"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/200/j0383528.gif" alt="" border="0" /&gt;&lt;/a&gt;&lt;a href="http://www.linkedin.com/pub/0/65a/875"&gt;Brandon Franklin&lt;/a&gt; recently asked the following question on AJUG (Australian Java Users Group) and SeaJUG (Seattle Java Users Group):&lt;/p&gt;&lt;p&gt;&lt;i&gt;At your company, are the { } placed using the Sun Standard, like this:&lt;/i&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public void method() {&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;br /&gt;&lt;i&gt;or using the "C way", like this:&lt;/i&gt;&lt;br /&gt;&lt;code&gt;&lt;br /&gt;public void method()&lt;br /&gt;{&lt;br /&gt;}&lt;br /&gt;&lt;/code&gt;&lt;/p&gt;&lt;p&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/j0290890.gif"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/200/j0290890.gif" alt="" border="0" /&gt;&lt;/a&gt;A day later, he posted the results of his survey back to these mailing lists. There were 68 responses: 35 from AJUG and 33 from SeaJUG. Basically there were three types of responses: same line opening bracket, next line opening bracket, and "either" or "no standard". And here is how each type was in favour:&lt;br /&gt;&lt;/p&gt;&lt;pre&gt;          &lt;span style="font-weight: bold;"&gt;SAME LINE     NEXT LINE/ALIGNED      EITHER&lt;/span&gt;&lt;br /&gt;AJUG         60%              37%                3%&lt;br /&gt;SeaJUG       58%              33%                9%&lt;br /&gt;COMBINED     &lt;span style="font-weight: bold;"&gt;59%              35%                6%&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;p&gt;&lt;/p&gt;&lt;p&gt;The conclusion that Brandon came to was that &lt;i&gt;the majority of Java development houses seem to use the Sun standard, with a solid third still using the "next line braces" approach.&lt;/i&gt;&lt;/p&gt;&lt;p&gt;I am not going to say which one you should choose. In my experience, the majority of companies I worked for used &lt;span style="font-style: italic;"&gt;same line&lt;/span&gt; style. In fact, all of them, but one used it. So the ratio in my case would be &lt;span style="font-weight: bold;"&gt;4:1&lt;/span&gt; for &lt;span style="font-style: italic;"&gt;same line&lt;/span&gt; style. When it comes to number of projects I worked on, it gets better (or worse, depending on how you look at it). The per projects ratio would be (and that's only because I can not remember all the small and small-ish projects I worked on)  somewhere around &lt;span style="font-weight: bold;"&gt;9:1&lt;/span&gt;.&lt;/p&gt;&lt;p&gt;Brandon also said that &lt;i&gt;It was not uncommon, in both camps, to have a person saying "While I support X, my company forces me to use Y."&lt;/i&gt;&lt;/p&gt;&lt;p&gt;And he also has the following message, which I completely agree with:&lt;/p&gt;&lt;p style="font-weight: bold;"&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://photos1.blogger.com/blogger/2606/2479/1600/j0379001.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: right; cursor: pointer;" src="http://photos1.blogger.com/blogger/2606/2479/200/j0379001.png" alt="" border="0" /&gt;&lt;/a&gt;&lt;i&gt;Those of you who support the Sun Standard but who are forced to use&lt;/i&gt;&lt;i&gt; the "C way" at work, I encourage you to take these results to your team and use them to strengthen your argument that the company is not following the majority of the industry in their code formatting.  Those of &lt;/i&gt;&lt;i&gt;you who are using the "C way", I would ask that you reconsider your stance in light of this information, and consider the value of industry standards above "personal preference".&lt;/i&gt;&lt;/p&gt;&lt;p&gt;But don't get me wrong! I do not mind using either style. After all, it's just a style, the real value is the code.&lt;/p&gt;&lt;p&gt;If you have a smart IDE then you can "see" the code through your prefered style without messing up the code that is in the common repository (and may be see in some other ways by others).&lt;/p&gt;&lt;p&gt;Which camp are you in?&lt;/p&gt;&lt;p&gt;Read more about Sun's official &lt;a href="http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html"&gt;Code Conventions for the Java Programming Language&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;script type="text/javascript"&gt;&lt;!--
google_ad_client="ca-pub-3388433133102440";
google_ad_width=160;
google_ad_height=600;
google_ad_format="160x600_as";
google_ad_type="text";
google_color_border="F6F6F6";
google_color_bg="F6F6F6";
google_color_link="B8A80D";
google_color_url="B8A80D";
google_color_text="9E5205";
//--&gt;&lt;/script&gt;
&lt;script type="text/javascript"
  src="http://pagead2.googlesyndication.com/pagead/show_ads.js"&gt;
&lt;/script&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/23939980-115006860136303428?l=hanuska.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://hanuska.blogspot.com/feeds/115006860136303428/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=23939980&amp;postID=115006860136303428' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115006860136303428'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/23939980/posts/default/115006860136303428'/><link rel='alternate' type='text/html' href='http://hanuska.blogspot.com/2006/06/code-conventions.html' title='Code Conventions'/><author><name>Dushan Hanuska</name><uri>http://www.blogger.com/profile/11568089987006666223</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='32' height='32' src='http://static.flickr.com/121/buddyicons/97304820@N00.jpg?1159788693'/></author><thr:total>0</thr:total></entry></feed>
