<?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-7280289311359063322</id><updated>2011-08-02T04:38:45.253-07:00</updated><category term='Comparator'/><category term='Java'/><category term='sucks'/><category term='constructor'/><category term='code generation'/><title type='text'>Javashlook</title><subtitle type='html'>A blog about all that sucks in the world of Java.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://javashlook.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7280289311359063322/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://javashlook.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>stanasic</name><uri>http://www.blogger.com/profile/07592005227779006558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>2</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-7280289311359063322.post-7582594700833166996</id><published>2007-11-16T03:11:00.000-08:00</published><updated>2007-11-16T06:30:56.026-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Comparator'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='code generation'/><title type='text'>Code generation for fun and profit, Part I</title><content type='html'>&lt;h2&gt;Problem statement&lt;/h2&gt;Let’s say you need to sort a bunch of beans in your enterprise application.&lt;br /&gt;&lt;br /&gt;Now, first of all and by all means, try to use the underlying database. Database management systems are written and highly optimized for data retrieval and ordering. In pure SQL, ordering is as easy as appending ORDER BY at the end of your SQL statement, and you should only invest some time into considering how to define columns and their direction programmatically. ORM solutions, like &lt;i&gt;Hibernate&lt;/i&gt;, make the job even easier with &lt;b&gt;Criteria&lt;/b&gt; queries and the like.&lt;br /&gt;&lt;br /&gt;But, sometimes you really need to sort some data in memory, before you hand it over to the database. Typical example of this scenario is integration or data import with some other, legacy, system. Of course, Java has a &lt;b&gt;Collections.sort()&lt;/b&gt; method, which, in case of non-&lt;b&gt;Comparable&lt;/b&gt; entities, requires an implementation of &lt;b&gt;Comparator&lt;/b&gt; interface. Its &lt;b&gt;compare()&lt;/b&gt; method is used to define ordering of beans in a collection.&lt;br /&gt;&lt;br /&gt;Typical comparator implementation, handling some example &lt;b&gt;TestBean&lt;/b&gt;, might look something like this:&lt;pre&gt;&lt;div style="font-size:85%; overflow: auto;"&gt;public class TestBean {&lt;br /&gt;   private Integer i;&lt;br /&gt;   private String s;&lt;br /&gt;   private Date d;&lt;br /&gt;…&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;public class ExampleComparator implements Comparator {&lt;br /&gt;   // I, S, D&lt;br /&gt;   public int compare(Object o1, Object o2) {&lt;br /&gt;       TestBean b1 = (TestBean)o1;&lt;br /&gt;       TestBean b2 = (TestBean)o2;&lt;br /&gt;&lt;br /&gt;       int c1 = ComparatorHelper.compare(b1.getI(), b2.getI());&lt;br /&gt;       if (c1 != 0) return c1;&lt;br /&gt;&lt;br /&gt;       int c2 = ComparatorHelper.compare(b1.getS(), b2.getD());&lt;br /&gt;       if (c2 != 0) return -c2; // descending order&lt;br /&gt;&lt;br /&gt;       return ComparatorHelper.compare(b1.getD(), b2.getD());&lt;br /&gt;   }&lt;br /&gt;}&lt;/div&gt;&lt;/pre&gt;Here the common comparing functionality has been extracted into a utility method:&lt;pre&gt;&lt;div style="font-size:75%; overflow: auto;"&gt;public final class ComparatorHelper {&lt;br /&gt;   private ComparatorHelper() {}&lt;br /&gt;&lt;br /&gt;   public static int compare(Comparable x, Comparable y) {&lt;br /&gt;       if (x == y) {&lt;br /&gt;          return 0;&lt;br /&gt;       }&lt;br /&gt;       else if (x == null) {&lt;br /&gt;          return Integer.MIN_VALUE;&lt;br /&gt;       }&lt;br /&gt;       else if (y == null) {&lt;br /&gt;           return Integer.MAX_VALUE;&lt;br /&gt;       }&lt;br /&gt;       else {&lt;br /&gt;           return x.compareTo(y);&lt;br /&gt;       }&lt;br /&gt;   }&lt;br /&gt;}&lt;/div&gt;&lt;/pre&gt;First problem with this approach is when you have several different classes to sort. Furthermore, you might want only particular columns, and in different orders, for each of those classes, to be considered in sorting process. And that should somehow be programmatically determined, rather than being hard-coded.&lt;br /&gt;&lt;br /&gt;All of the above would necessitate having to write separate &lt;b&gt;Comparator&lt;/b&gt; classes for each and every combination. While you may think that writing a generic comparator with bunch of ifs or such might do the trick, at least for a single class, there is still a performance issue, since &lt;b&gt;compare()&lt;/b&gt; method will be invoked extensively in a sorting algorithm.&lt;br /&gt;&lt;h2&gt;Enter code generation&lt;/h2&gt;Ideally, we would generate our Comparator implementation, according to the desired parameters, on-the-fly. Something like this would be nice:&lt;pre&gt;&lt;div style="font-size:85%;overflow: auto;"&gt;&lt;br /&gt;Comparator&amp;lt;Testbean&amp;gt; c1 = ComparatorFactory.createComparator(TestBean.class,&lt;br /&gt;                                   new String[] { "i", "s", "d" },&lt;br /&gt;                                   new Class[] { Integer.class, String.class, Date.class },&lt;br /&gt;                                   new int[] { 1, -1, 1 });&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;Meaning of the above should be self-explanatory, but just in case: it is expected that the above method creates a comparator for &lt;b&gt;TestBean&lt;/b&gt; class, where properties &lt;b&gt;i, s&lt;/b&gt; and &lt;b&gt;d&lt;/b&gt; are compared in that order, and &lt;b&gt;s&lt;/b&gt; property will be descending. The above argument format is, truth be told, very impractical for interfacing with other parts of the system. Better approach would be using a method chaining parameter class, something like this:&lt;pre&gt;&lt;div style="font-size:85%;overflow: auto;"&gt;&lt;br /&gt;Comparator&amp;lt;Testbean&amp;gt; c1 = ComparatorFactory.forClass(TestBean.class)&lt;br /&gt;                                  .addProperty(“i”, Integer.class)&lt;br /&gt;                                  .addProperty(“s”, String.class, false)&lt;br /&gt;                                  .addProperty(“d”, Date.class)&lt;br /&gt;                                  .generate();&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;But I will be leaving that as an exercise for junior developers… Nah, I’ll just do it later; I really like those &lt;i&gt;fluent interfaces&lt;/i&gt;.&lt;br /&gt;&lt;br /&gt;Now back to the code generation bit. The algorithm for a comparator is pretty straight-forward: for each property, compare values using &lt;b&gt;ComparatorHelper&lt;/b&gt;. If returned value is non-zero, return it, possibly calculating in the descending order. Otherwise, compare the next property.&lt;br /&gt;&lt;br /&gt;This post is getting quite long by now… so I have to say goodbye for now. Stay tuned for sequel where I’ll be using the &lt;i&gt;CGLIB&lt;/i&gt; library, and will be providing actual code.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7280289311359063322-7582594700833166996?l=javashlook.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javashlook.blogspot.com/feeds/7582594700833166996/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7280289311359063322&amp;postID=7582594700833166996' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7280289311359063322/posts/default/7582594700833166996'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7280289311359063322/posts/default/7582594700833166996'/><link rel='alternate' type='text/html' href='http://javashlook.blogspot.com/2007/11/code-generation-for-fun-and-profit-part.html' title='Code generation for fun and profit, Part I'/><author><name>stanasic</name><uri>http://www.blogger.com/profile/07592005227779006558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-7280289311359063322.post-3947911756998063987</id><published>2007-10-24T06:22:00.000-07:00</published><updated>2007-11-16T06:28:07.687-08:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='constructor'/><category scheme='http://www.blogger.com/atom/ns#' term='Java'/><category scheme='http://www.blogger.com/atom/ns#' term='sucks'/><title type='text'>Stupid Java superclass constructors</title><content type='html'>&lt;p&gt;&lt;br /&gt;Apparently, constructors in Java suck. Consider a following example:&lt;/p&gt;&lt;pre&gt;&lt;div style="font-size:85%;overflow:auto;"&gt;public class Page {&lt;br /&gt;  protected int page;&lt;br /&gt;  protected int pageSize;&lt;br /&gt;  protected List result;&lt;br /&gt;&lt;br /&gt;  public Page(int page, int pageSize) {&lt;br /&gt;    this.page = page;&lt;br /&gt;    this.pageSize = pageSize;&lt;br /&gt;    findResult();&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  protected void findResult() {&lt;br /&gt;    // do something with page &amp;amp; pageSize&lt;br /&gt;    result = doQuery(…, page, pageSize);&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  public List getResult() {&lt;br /&gt;    return result;&lt;br /&gt;  }&lt;br /&gt;}&lt;/div&gt;&lt;/pre&gt;&lt;p&gt;Now you want to introduce a subclass which contains different implementation of &lt;b&gt;findResult()&lt;/b&gt;. But, let’s also say you decide you want to use an additional parameter.&lt;/p&gt;&lt;pre&gt;&lt;div style="font-size:85%;overflow:auto;"&gt;public class OrderedPage {&lt;br /&gt;&lt;br /&gt;  protected int sortColumn;&lt;br /&gt;&lt;br /&gt;  public OrderedPage(int page, int pageSize, int sortColumn) {&lt;br /&gt;    super(page, pageSize);&lt;br /&gt;    this.sortColumn = sortColumn;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  protected void findResult() {&lt;br /&gt;    // do something with page &amp;amp; pageSize &amp;amp; sortColumn&lt;br /&gt;    …&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p&gt;Well, the problem is that &lt;b&gt;sortColumn&lt;/b&gt; field in the above class will be uninitialized when &lt;b&gt;findResult()&lt;/b&gt; methods is invoked.&lt;br /&gt;&lt;br /&gt;If you’re pressed for time and able to change the base class, you can add a protected, no-arg constructor, and repeat the whole initialization and the method call of &lt;b&gt;findResult()&lt;/b&gt;  in the &lt;b&gt;OrderedPage&lt;/b&gt; class again. The cleanest approach would involve rewriting all the public getters, like &lt;b&gt;getResult()&lt;/b&gt; according to &lt;i&gt;lazy-loading&lt;/i&gt; approach, and remove the invocation from the base class constructor. Like this:&lt;/p&gt;&lt;pre&gt;&lt;div style="font-size:85%;overflow:auto;"&gt;&lt;br /&gt;public List getResult() {&lt;br /&gt;  if (result == null) {&lt;br /&gt;    result = findResult();&lt;br /&gt;  }&lt;br /&gt;  return result;&lt;br /&gt;}&lt;br /&gt;&lt;/div&gt;&lt;/pre&gt;&lt;p&gt;However, you might have a situation where there are multiple getters to change. Altering them, apart from being a tedious job, might involve slight semantic changes to a class eg. a variable declared &lt;b&gt;final&lt;/b&gt; will have to be “unfinalized”.&lt;br /&gt;&lt;/p&gt;&lt;p&gt;And, let’s not forget, you might not actually be able to change the base class.&lt;/p&gt;&lt;p&gt;There is, of course, a hack. It consists of using a static method and &lt;b&gt;ThreadLocal&lt;/b&gt; variable:&lt;/p&gt;&lt;div style="font-size:85%;overflow:auto;"&gt;&lt;pre&gt;public class OrderedPage {&lt;br /&gt;&lt;br /&gt;  &lt;b&gt;private static final ThreadLocal&lt;integer&gt;&amp;lt;Integer&amp;gt; threadSortColumn = &lt;br /&gt;      new ThreadLocal&amp;lt;Integer&amp;gt;&lt;integer&gt;();&lt;/integer&gt;&lt;/integer&gt;&lt;/b&gt;&lt;br /&gt;&lt;br /&gt;  private static int hack(int pageSize, int sortColumn) {&lt;br /&gt;    &lt;b&gt;threadSortColumn.set(Integer.valueOf(sortColumn));&lt;/b&gt;&lt;br /&gt;    return pageSize;&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  protected int sortColumn;&lt;br /&gt;&lt;br /&gt;  public OrderedPage(int page, int pageSize, int sortColumn) {&lt;br /&gt;    super(page, hack(pageSize, sortColumn));&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;  @Override&lt;br /&gt;  protected void findResult() {&lt;br /&gt;    // do something with page &amp;amp; pageSize &amp;amp; sortColumn&lt;br /&gt;   &lt;b&gt;sortColumn = threadSortColumn.get().intValue();&lt;/b&gt;&lt;br /&gt;   …&lt;br /&gt;  }&lt;br /&gt;&lt;br /&gt;}&lt;/div&gt;&lt;/pre&gt;&lt;p&gt;Quite surprisingly, it doesn’t look that bad! And it will confuse the hell out of the junior developers, as well as senior wannabes.&lt;/p&gt;&lt;p&gt; Code tight!&lt;br /&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/7280289311359063322-3947911756998063987?l=javashlook.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://javashlook.blogspot.com/feeds/3947911756998063987/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=7280289311359063322&amp;postID=3947911756998063987' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/7280289311359063322/posts/default/3947911756998063987'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/7280289311359063322/posts/default/3947911756998063987'/><link rel='alternate' type='text/html' href='http://javashlook.blogspot.com/2007/10/stupid-java-superclass-constructors.html' title='Stupid Java superclass constructors'/><author><name>stanasic</name><uri>http://www.blogger.com/profile/07592005227779006558</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry></feed>
