Wednesday, September 14, 2011

Regular expression cheat sheet

.Any character
^Start of line
$End of line
\dDigit character
\DAny character except digits
\sWhitespace character
\SAny character except whitespace
\wWord character
\WAny character except word characters
\bWord boundary
()Grouping
(x|y)x or y
x*Zero or more occurrences of x
x+One or more occurrences of x
x?Zero or one occurrences of x
x{m,n}At least m and at most n occurrences of x
x{m}Exactly m occurrences of x
[a-f]Character class containing a,b,c,d,e,f
(?is:x)Switch mode when evaluating x. i turns on ignoreCase, s means single-line mode

  • Symbols tend to have the same first letter as what they represent. Uppercase symbols define the complement. 
  • Use grouping properly: ab+ matches abbbb but (ab)+ matches ababab

Wednesday, June 1, 2011

Warning if leaving a form with unsaved changes

I had a requirement to show a warning if the user was about to leave a form with unsaved changes.

One approach is to save the contents of form fields when the document is loaded and then register an "onbeforeunload" function that compares the current values with the values saved previously.


This is actually quite easy to do with jQuery. One simple approach is the following:

The serialize() function encodes form elements as a String. In this case it's all the input fields contained in a form but it could be some other HTML element.

After that it's all a matter of calling a function that will decide if the warning will be displayed or not. Returning any text from the onbeforeunload event displays a standard warning upon leaving a page.

Monday, February 14, 2011

Some more misunderstanding

Very good blog entry by Joakim Holm: the big misunderstanding.

Since the comments are closed I'd like to add that this terminology completely focused on "building" explains why some people think that programmers a.k.a "builders" are interchangeable, like lego bricks. So if you need to replace programmer A in team X because he or she quit all you have to do is call upon programmer B. Then team X will be complete again like nothing had happened.

Related to this is the fact that teams that work well and manage to produce value during a project are usually "disbanded" at the end of that project with all the knowledge gathered during the team's retrospectives, etc lost or at least scattered in documents or wikis that no one will read.
When did you see a good football team that won Champions League being "disbanded"? Never, of course, because it doesn't make sense. The sensible thing is to keep the team together for another project and another...you don't want to let go off your good team...or you shouldn't...

Clearly, we (software developers) are failing to communicate as a group that there's value in keeping good teams together, that there's value in the experience of seasoned developers, that there's value in good design, that it's not just about "building", that knowledge work is not about Lego, and so on.

The ones making the big decisions (but of course there are exceptions!) are not seeing the value in all the above which is surprising since:

Software-dependent businesses can only evolve as fast as their ability to write and evolve their software allows them to (Gorman's Law Of Software-Dependent Business Evolution)

Maybe we need to raise our game.

Wednesday, February 9, 2011

Hibernate, JSF 2 and ManyToMany

It can be quite a bit of a headache if you have multiple checkboxes (or similar) that are mapped to a @ManyToMany relationship using JSF 2 and Hibernate JPA.


In this case, the selectManyCheckbox is mapped to a Set which is annotated with @ManyToMany using a join table. If you want to avoid repeated LIEs when submitting the form you need to add the following attribute:

collectionType="java.util.HashSet"

to h:selectManyCheckbox.

If you use the Hibernate JPA persistence provider and choose default or lazy as the association fetch value an org.hibernate.LazyInitializationException exception can occur at runtime unless you set the collection type. This problem is apparently specific to Hibernate JPA.

Thursday, February 3, 2011

Less (looping) noise with lambdaj

 I know a Java developer who became a project manager when he couldn't stand the pain of having to write yet another loop ;)

If you're stuck with Java and can't use Groovy or less noisy languages, how about doing more with less?

Lambdaj to the rescue! Lambdaj is a powerful library that allow us to manipulate collections in a psudo-functional and statically-typed way. Just a a couple of examples:

Let's say that a collection of task objects and I want to collect the id for each of them.

With your regular Java loop you'd probably write:

With lambdaj I'd write:

OK, that was just one line!

Let's say I want to filter the roles equal to "admin"

The iterative version:


And with lambdaj:

And there's more. Another common task while working with collections is to aggregate their items in some way. Let's say that we have a list of tasks objects with end dates and I want to get the max end date for all of them.

Without lambdaj's aggregating functions:

With lambdaj you just write:
maxFrom(tasks).getEndDate();

This is just a small taste. See more features here: http://code.google.com/p/lambdaj/wiki/LambdajFeatures

Download http://code.google.com/p/lambdaj/ and loop less!

Friday, January 7, 2011

Smooth queries with QueryDSL

Have you ever used Hibernate's criteria API and thought it could be more intuitive?

Do you think that JPA2's criteria typesafe queries are hard to read?

Then I recommend that you take a look at the following project

Compare this code: with this one:


Now it's typesafe and MUCH smoother and intuitive.

Check the following page for more examples of QueryDSL vs JPA2 Criteria

QueryDSL makes it easy (at last) to work with criteria queries. Did I mention that it can also be used with JDO, Lucene, JDBC and even plain collections?

For example if you are already using QueryDSL to replace the plain criteria API then you are all set to query any collections containing your domain objects anywhere in your code :). All you need to do is import the collections API.

This code would then replace your typical loop.

Congratulations to Timo Westkämper and to the QueryDSL team!