The week before last was an interesting one. Apart from the usual chaos at our workplaces, we finally had our chance to get some hands-on experience with play! Simply put, it was one of the most pleasing two days of time developing, and the result was probably the best, for two days that is.
First of all i (@agaoglu) wasn’t anywhere near any web application for about 6 months now, so it can be said that i’m somewhat rusty. But i was onto some serious hadoop stuff, so my java blade is sharper than ever. @burakdalgic on the other hand, was simply harvesting his crops of PHP for almost a year and looking for some other ingredients to open his next brewery.
Anyway, @burakdalgic called me on Thursday afternoon to inform me that they would be needing a registrations tool for their front desk at 27th National Congress of IT (27. Ulusal Bilişim Kurultayı[in turkish]). Organizer of the congress had recently bought some barcode readers and by utilizing them, they wanted reports about participants of select sessions. Along with barcode readers, they were supplied with a software to record some details of participants which is developed with Excel/Access and somehow is unable to generate any reports, but that’s another story. When i asked about our deadline, he simply answered the event would start on Wednesday so there were 5 days ahead. I said OK thinking some sleepness nights on weekend is nothing new. Prior to that OK, I didn’t consider any frameworks or languages apart from that it wasn’t going to be any flavor of JavaEE nor PHP.
That evening at home after some chillout music and some rest cured my headache, two choices shined out of the dark: Django and play!. We had experience with Django and a small application like that was nothing compared to what we had been able to achieve with it. Beyond capabilities, it was the fastest-to-work-with environment i had ever been into. Generating HTML form out of the Model class was a huge performance boost but the templating was making up for it. Then i remembered: working in django, i always needed 3 virtual desktops. One for browser, one fore IDE (which is vim) and one for terminal that ‘$ django runserver’ was outputting. Whenever a error happens, django was generating an HTML report to tell me about it in the browser, but since that almost never made sense, i had to go to the terminal to see that i was actually comparing a string with an int in an entirely different place. I know this is not a django problem but a dynamically-typed language problem but it is not my problem now is it? Another problem was ‘$ django runserver’ was not the way to go in production, so we would be forced to deploy some web server, configure it and have another point of failure which is not what we want in a front desk of a conference.
So as the night goes darker one option was becoming brighter: play! Which actually had a bigger problem: we had zero experience with it. Apart from some tests with CRUD module and regular reading of their mailing list, we had no idea how to work it out. Well, we knew it was on java, which is a statically-typed language, which in turn has some great IDEs like eclipse which tell you it is not possible to compare a String with an int, as soon as you write it. That’s what i call a performance boost by the way. On the other hand i was remembering things about play having its own netty powered web server and the recommended way of running a play application was ‘$ play run’ indeed. That way we would able to track down any problems at that front desk more easily, since there would be only one place to look at. So, around 9pm that night i overlooked the lack of experience and take a leap of faith by pulling play/1.1 branch from launchpad.
With the help of ‘$ play help’ project had a structure, eclipsified and was running in no time. After some layout with jquery-ui (which quite sums up what i know about UI), we got our first screen that would be simply the C in a CRUD for our participant model.

After a few trips to documentation i got the form wired to my application code and was able to save entries to database with just one line, thanks to Active-Record-like interface for JPA stuff.
public static void save(Participant participant){
participant.save();
show(participant.id);
}
Manually constructing jdbc connections in JNDI, wiring it to JTA and informing hibernate to create the EntityManagerFactory out of that mess, so that i can create my EntityManager to do the same save(), just went out of the window. I don’t even want to remember the things i should have done in a web.xml and any other framework related xml just to wire that form to my application code. I know almost all of the xml-required-frameworks have some eclipse plugins to automate these processes but in my experience they rarely work. And when they work, it’s just for a time to understand they are not capable enough so back to manual. Besides, there are times when it is not possible to use any IDE. play!, with its out-of-the-ordinary package naming scheme, really shines here. It is extremely optimistic to edit something in com/spp42/plevsy/track/controller/Participants.java, compile it to get a war (which you need a previously written ant build at best) and expect it to work just after deploying on tomcat. With play!, it is simply ‘$ vim controllers/Participants.java’ and hitting reload. No need to ant-build or deploy or even quit vim.
Next, we needed the first core functionality which is barcode generation. Quick googling lead me to barbecue and within minutes i was able to output barcodes in PNG. That completed R in that CRUD.
public static void barcode(Long id)
throws BarcodeException, OutputException{
Participant participant = Participant.findById(id);
Barcode barcode = BarcodeFactory.createCode128(
participant.code);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
BarcodeImageHandler.writePNG(barcode, baos);
ByteArrayInputStream bais = new ByteArrayInputStream(
baos.toByteArray());
renderBinary(bais);
}

I remember a good friend of mine struggling to modify a PDF generation in django for days without a result because library wasn’t in a good shape. I might remember that wrong, but i think noone’s gonna argue that the library diversity in java beats the hell out of anything out there.
I committed what i have so far to svn around 11pm and went to bed. That was one less sleepless night for me. Friday morning, at work, i had some free time to finish U and D of the CRUD which took about five minutes combined. I somewhat felt experimental and look into some HTML5 input types which resulted in our participant listing to be more like google instant! (OK that was a bit off). But i didn’t take me more than fifteen minutes.
First what seems to the user
<div class="toolbar search ui-widget-header ui-corner-all">
<input
type="search"
name="q"
id="q"
class="search ui-widget ui-corner-all"
value="${session.q}"
incremental="true" />
<button class="search">Search</button>
</div>
<div class="list">
<ul class="partlist clean">
</ul>
</div>
Then what is on user but does not seem
$('button.search')
.button({text:false,icons:{primary:'ui-icon-search'}})
.click(doSearch);
$('#q').bind('search', doSearch);
function doSearch(e) {
$.get("@{Participants.search()}",
{q: $('#q').val()},
function(data){
$('ul.partlist').html(data);
});
}
And in server
public static void search(String q){
List result = Participant.find(
"lower(name) like ? or " +
"lower(lastname) like ? " +
"order by lastname",
q+"%".toLowerCase(), q+"%".toLowerCase()).fetch();
session.put("q", q);
render(result);
}
which outputs
#{list result, as:'p'}
<li>
<a class="ui-widget ui-widget-content"
href="@{Participants.show(p.id)}" >
${p.name} ${p.lastname} (${p.id})
</a>
</li>
#{/list}
And as a result

That afternoon i had some more time to implement barcode checkins so i called @burakdalgic to learn that we would be getting a text file out of that barcode readers and users will be uploading them. As the documentation says, it could not be more simpler.
public static void install(Hall hall, File dump)
throws FileNotFoundException, ParseException{
Scanner scanner = new Scanner(dump);
while(scanner.hasNextLine()){
String line = scanner.nextLine();
String[] entry = line.split("\\|");
Date parsed = new SimpleDateFormat(
"dd.MM.yyyy hh:mm:ss").parse(entry[1]);
CheckIn checkIn = new CheckIn(entry[0], hall, parsed);
checkIn.participant = Participant.findById(
Long.valueOf(entry[0].substring(13)));
checkIn.save();
}
main();
}
In java that is. It would be more concise with functional programming paradigms and anyone who can’t live without them is free to use scala.
I filled my remaining free time trying to figure out how to generate a pie chart with flot which took something like 2 hours. Say, 3 minutes of that 2 hour went to write required jpa-ql so remaining 1 hour and 57 minutes seemed too much time for just a pie chart after all that work in play. Alright, lack of experience with flot is responsible for much of it but i knew almost nothing about play either. However could write a whole another application in that time. Wasting time on less important thing, i went to bed again on time, cause there were only a handful of things left to do.
Saturday morning, after a late breakfast, another 2 hours got me a fully working application with solid layout, barcode checkins, reports and CRUD screens. Sleepless nights aside, we went to the barbecue party at our friends’ house and got some alcohol into our systems. Sunday afternoon, we met to iron out some details about barcode data format, and i didn’t even need to tell anything about play. Because the code was just simple java methods, HTML and javascript; @burakdalgic was able to pick just where i left and move on[to his work of UI].

Well, i mentioned the effort took two days but it seems it wasn’t even whole two days. Just some hours scattered over a weekend and we had what we needed. I wasn’t at the operations or front desk so i don’t know how it went the first hand but that’s a good thing from another angle: they didn’t have major problems [apart from the problem that we started running it in development mode to have some crashes which was fixed as soon as we switched to production] so i didn’t have to be there. For a two day application that is a great technical outcome. And from what i have heard from my collegue, users were pleased with its usage and performance. ‘The bottle neck on the desk was the printer’ he said.