Monday, June 25, 2012

let me introduce you project Lombok

Problem: Have you ever been in a situation, when you tough that creating all those boring equals(), hashCode(), toString() methods is quite time consuming and maintaining these is error prone?
SolutionIf so, read on :) Project Lombok might be the answer.

Yesterday, while searching for some solution on this (with having in mind the tutorial of spring roo I've read quite some time ago where these could be handled by AOP using annotations) I've found as a possible solution project Lombok:
http://projectlombok.org

Lombok demo and features list
I really like their demo video, if you want an introduction to this project, make sure you watch it:
http://projectlombok.org/
And there is also quite nice feature list available: 
http://projectlombok.org/features/index.html

Encouragement
OK, so what's next? Am I brave enough to go for it? While doubing it I've found out I'm not the only one:
http://stackoverflow.com/questions/3852091/is-it-safe-to-use-project-lombok

That gave me some encouragement. So let's go and try it.

I have some small open source project, so let me show you my code prio and after the change to give you an overview (or rather motivation :)).

Code snippets comparison
See:
  • eclipse generated methods:
    // eclipse generated methods way
    public class Schedule implements Serializable {
    
    ...
    
     @Override
     public int hashCode() {
      final int prime = 31;
      int result = 1;
      result = prime * result + ((bgImage == null) ? 0 : bgImage.hashCode());
      result = prime * result + (blank ? 1231 : 1237);
      result = prime * result + (clear ? 1231 : 1237);
      result = prime * result + (live ? 1231 : 1237);
      result = prime * result + ((name == null) ? 0 : name.hashCode());
      result = prime * result
        + ((presentations == null) ? 0 : presentations.hashCode());
      return result;
     }
    
     @Override
     public boolean equals(Object obj) {
      if (this == obj)
       return true;
      if (obj == null)
       return false;
      if (getClass() != obj.getClass())
       return false;
      Schedule other = (Schedule) obj;
      if (bgImage == null) {
       if (other.bgImage != null)
        return false;
      } else if (!bgImage.equals(other.bgImage))
       return false;
      if (blank != other.blank)
       return false;
      if (clear != other.clear)
       return false;
      if (live != other.live)
       return false;
      if (name == null) {
       if (other.name != null)
        return false;
      } else if (!name.equals(other.name))
       return false;
      if (presentations == null) {
       if (other.presentations != null)
        return false;
      } else if (!presentations.equals(other.presentations))
       return false;
      return true;
     }
    
     @Override
     public String toString() {
      return "Schedule [presentations=" + presentations + ", bgImage="
        + bgImage + ", name=" + name + ", blank=" + blank + ", clear="
        + clear + ", live=" + live + "]";
     }
    
    }
    
  • Lombok way:
    // lombok way
    @ToString
    @EqualsAndHashCode
    public class Schedule implements Serializable {
    
    ...
    
    }
    
  • manually written ones with Equals/ToString/HashCode Builders:
    // manual way using Equals/ToString/HashCode Builders
    public class Schedule implements Serializable {
    
    ...
    
     @Override
     public int hashCode() {
      return new HashCodeBuilder()
      .append(this.getPresentations())
      .append(this.getBgImage())
      .append(this.getName())
      .append(this.isBlank())
      .append(this.isClear())
      .append(this.isLive())
      .toHashCode();
     }
    
     @Override
     public boolean equals(Object obj) {
      if ( !(obj instanceof Schedule) ) return false;
      Schedule castOther = (Schedule) obj;
      return new EqualsBuilder()
       .append(this.getPresentations(), castOther.getPresentations())
       .append(this.getBgImage(), castOther.getBgImage())
       .append(this.getName(), castOther.getName())
       .append(this.isBlank(), castOther.isBlank())
       .append(this.isClear(), castOther.isClear())
       .append(this.isLive(), castOther.isLive())
       .isEquals();
     }
    
     @Override
     public String toString() {
      return new ToStringBuilder(this)
      .append("\n presentations", this.getPresentations())
      .append("\n bgImage", this.getBgImage())
      .append("\n name", this.getName())
      .append("\n blank", this.isBlank())
      .append("\n clear", this.isClear())
      .append("\n live", this.isLive())
      .append("\n")
      .toString();
     }
    
    }
    
So as obvious from the samples, instead of writing/maintaining the code you can rather just annotate. (Btw. if there were no lombok way, I'd go for Builders way => manual writing + maintaining).

Integration
The great thing is that there is a simple integration with maven (that is the build tool of my choice). See instructions:
http://projectlombok.org/mavenrepo/index.html
Moreover integration with Eclipse seems really straitforward too (all the autocompletition as well as Outline view work as expected or rather unexpectedly well).

Some more motivation
To encourage lazy developers (like me) even more, there are things available for:
- getters and setters (@Getter, @Setter)
- logging (depending on your logging library: @CommonsLog, @Log, @Log4j, @Slf4j)
- there is even more, but for the rest I might not be brave enough ( yet :))

Behind the scenes
OK, sounds nice, but how it works internally?
In fact lombok generates expected methods/fields to the target class. So the nice thing is that you don't need it during runtime/deployment. Once compiled, classes will contain the stuff.

How do you guys feel about it? Would you give it a try? Or do you have some other approach on this? Feel free to share your ideas/feelings.

code syntax highlighting in blog posts


Problem: Need to syntax highlight the code in the blog posts (to improve it's readability).
Solution: github's gist (http://gist.github.com/)

OK now what's the story? I tried to find some simple solution for me to be used in the blogger.com in the dynamic templates.
I've found: gist. 
As one of the quite popular proposals on stackoverflow said :
http://stackoverflow.com/questions/679189/formatting-code-snippets-for-blogging-on-blogger

What is gist?
(Copy pasted from their site) "Gist is a simple way to share snippets and pastes with others. All gists are git repositories, so they are automatically versioned, forkable and usable as a git repository."

Sounds good. But when trying it didn't work for the blogger and dynamic templates.
After some googling found following post:
http://blog.moski.me/2012/01/gist-with-bloggers-dynamic-views.html
and that worked for me!

So since from now on, you can expect some nicely highlighted code snippets in my posts :)

Repost new blog notification to social networks

Problem: How to automatically send status notifications on the new blog posts on blogger to google+, facebook and twitter?
Solution: Two step approach worked for me:
1. use official blogger to google+ integration (to post to google+)
2. use "+Rob Mcgee" (to repost from Google+ to facebook and twitter)

How to achieve it? Go on reading.

Official integration blogger to google+.
Follow the instructions here:
http://support.google.com/blogger/bin/answer.py?hl=en&answer=1752748
Or more specifically, to merge the profiles do so here:
http://www.blogger.com/switch-profile.g

Google+ to Facebook and Twitter reposting
Use the site with the official instructions: http://gplus.sagg.im/
I've found this approach on:
http://lifehacker.com/5868019/how-can-i-post-to-facebook-twitter-andor-google%252B-all-at-the-same-time

In fact I need to test it somewhere, so if you see this post in all these 3, it should be working fine.
Let's see :)