Thursday, May 6, 2010

Groovy wrapping of long table td text with no blanks

Subtitle: Groovy's a Wrap

Just today I had a client -- who had just tested a fairly complex GSP -- ask to have text in a table data element wrap. He had tested it with a long string of characters with no spaces. He wanted:

asldfjas;fjasodfsaodjfsaodfdsadfa;ljlj

To show as:

asldfjas;fj
asodfsaod
jfsaodfdsa
dfa;ljlj

And not just the first 12 characters that fit in the td.


Quick solution: Hey buddy, use spaces and the browser will wrap for you.
Groovy solution: Insert thespaces for them.

I took the Groovy option. What I did was extend the String class in BootStrap to have a wrapAt method:


class BootStrap {

def init = { servletContext ->
String.metaClass.wrapAt = {width ->
matcher = (delegate =~ /\w{1,$width}/);
def that = ''
matcher.each {
that += "${it.trim()} "
}
return that
}
}
def destroy = {
}
}


Then, in my GSP (where the em width was 12) I added:

<td>${option.value.wrapAt(12)}</td>


I tested the code with the following:


String.metaClass.wrapAt = {width ->
println delegate
matcher = (delegate =~ /\w{1,$width}/);
def that = ''
matcher.each {
that += "${it.trim()} "
}
return that
}

def str = 'one two thetimehascomeforalgoodmentocometotheaidoftheircountry'
assert "one two thetimehas comeforalg oodmentoco metotheaid oftheircou ntry " == str.wrapAt(10)


Sure, not a perfect solution, but all the text the user keyed is viewable on the page (and the optional PDF that is generated from that page.) It looks like this:

one two
thetimehasco
meforalgoodm
entocometoth
eaidoftheirc
ountry

Also, it gave me a use for Groovy meta programming

Friday, April 16, 2010

Kindle for Technical Content

I'm a reader. I started reading novels at a very young age. As a developer and reader, I'm addicted to reading technical books. I am also a technical writer so I'm constantly buying and reading books. And I'm not a fan of reading on-line. When I sit in front of my PC, I expect the instant gratification of coding or writing. I find it difficult to read a PDF book cover-to-cover (or should that be byte-to-byte?) Case in point: To save money, I opted for the PDF version of Venkat Subramaniam's "Programming Groovy: Dynamic Productivity for the Java Developer." Great book, by the way. But I ended up getting frustrated and printed the book -- which ended up costing me more in paper and ink than that print version would have.

A month ago I was at Barnes and Nobles and I became intrigued by the Nook. The Nook is B&N's book reader. I almost bought it. Luckily I backed out of the store and began researching the Nook and compared it with Amazon's Kindle.

The Nook is pretty neat but, unlike the Kindle, it does not have a keyboard. With the Nook, you can bookmark your documents -- but you can't highlight text or add notes. The Kindle has an integrated keyboard and you can highlight and add notes.

I got my Kindle yesterday. And, so far, I love it.

Book Availability:

I am currently researching Cloud Computing for use in Grails applications using both Amazon Web Services and Google App Engine. To that end I've been wanting to buy two books: "Programming Amazon Web Services" and "Programming Google App Engine" (both from O'Reilly.) Curiously, the Amazon book was not available for Kindle at Amazon's site but the Google book was. So I bought the GAE book from Amazon and went to the O'Reilly site for the AWS book. At O'Reilly I found that they do make an eBook download available that is Kindle compatible (.mobi.) O'Reilly gives you both the Kindle and PDF versions of the book. To get the AWS book's mobi file on my Kindle I simply plugged in the Kindle's USB and copied the mobi file from my PC to the Kindle's documents directory.

My next issue was that I wanted to get some of my PDF books on the Kindle. All I had to do was plug in the USB and copy the PDFs from the PC to my Kindle. There are two issues with PDF on the Kindle: 1) It shows the entire page on the screen, which requires a very small font (but it is readable). 2) While you can add bookmarks to a PDF, you can't add notes or highlight text. Note that I believe there are PDF to mobi converters available. But, for right now, I'm happy with Kindle's PDF reader.

Reading Experience:

I was reticent to get an electronic reading device because I thought I needed the spacial context of a printed book. When I first get a printed copy of technical book, I put a half-dozen sticky notes inside the front cover. Then I hook a highlighter and a mechanical pencil on the back cover. I use the sticky notes to bookmark important sections and my current page. Those sticky notes stay in the book forever. When I go to my book shelve, I usually find what I'm looking for by going to the various bookmarked pages.

As I read my print books, I use the highlighter on important sections and I use the pencil to make notes. If I'm doing research for an article, I also write notes on the front cover with page references.

The Kindle does all that for me only in a cleaner, greener fashion. First off, I love that when I put the Kindle down (which has been difficult) and power it off and then later return to the Kindle and power it back on, it goes right to the page of the document that I was last reading. I also love that I can make bookmarks with notes and then Kindle shows me my bookmarks, notes, and highlights in an easy to read index. For article research, the notes are invaluable. For programming, the bookmarks and highlights are extremely useful.

I was also concerned about the display of tables and code on the Kindle. But I discovered that the Kindle allows you to change the view from portrait to landscape (a feature the Nook does not provide.) The Kindle also allows you to change your font size (which the Nook allows as well.)

At any rate... I'm loving my Kindle

Monday, February 8, 2010

Free Book on Grails

Three years ago, when I first began developing with Grails, I benefited from a book by Jason Rudolph called "Getting Started with Grails" The book was well written, short, and available as a free PDF. I recommended it to everyone interested in Grails. But, as Grails rapidly improved, the book began to become outdated.

No longer.

Jason Rudolph teamed up with Scott Davis (author of "Groovy Recipes") to update the book. It now covers Grails 1.2 and, once again, I highly recommend it.
You can download the book from:
http://www.infoq.com/minibooks/grails-getting-started
But note that InfoQ will ask you to register with their site before you can download the PDF. But it is well worth it as InfoQ is a great site with lots of technical information, in form of articles and videos, on application development.

Friday, February 5, 2010

Comment on IE

Half my work is creating Web solutions for my clients.
The other half of my work is getting it to work on Internet Explorer....

Real World Observation about Grails

In the past 3 years I've developed 7 Grails applications for a variety of customers. And I have to make an observation: Maintaining Grails applications is a breeze. It is far more easy than with any other development platform I've used. I've had to revisit Java applications that I had written. But it always takes me a while to figure out the design strategies. For instance: what MVC pattern did I use?

With Grails applications -- whether written by myself or not -- the MVC is always the same. The directory structure is always the same. It is fabulous being able, in Eclipse, to switch workspaces from one Grails project to another and have the structure look identical. They look so similar sometimes, when I come back from lunch or something, I have think "OK, what project is this."

This is an observation of the benefits of the Grails philosophy of "Convention over Configuration." This Grails feature provides a huge ROI when someone else can take over a Grails project and know where everything is. In fact, I benefited from this myself two years ago when I joined an existing Grails project team. The project was Circuit City's return system (I have some gift cards if anyone would like to buy them). The return system had been in production for a year and it was very complex (for example it had DB connections to Informix, Oracle, and DB2i.) Yet I was able to be productive in a very short time after joining the project. By the way, that Grails app is the only Grails app that I worked on that is no longer in use -- for obvious reasons....

Grails makes life easier.

Book Review: Grails: A Quick-Start Guide

It's been 5 months since my last post. I have dozens of times thought "I need to post this." But -- as I was working 12X7 on a major Grails-based order entry system and two other smaller Grails projects and authored 3 articles on Grails and delivered a multi-city seminar tour on Grails -- I simply didn't have the time. But things are slowing down now.

I recently burned through The Pragmatic Programmer's new book: "Grails: A Quick-Start Guide" by Dave Klein. I was impressed. Attendees to my seminars and Grails mentees usually ask "What's a good book to buy on Grails?" Well, "The Definitive Guide to Grails" authored by the creator of Grails, Graeme Rocher, is a bit too long for beginners. I think of it as the Grails bible. "Grails in Action," by Glen Smith and Peter Ledbrook, is fabulous as it is very written. But its 487 pages can be a bit daunting. "Grails: A Quick-Start Guide" is very approachable. It is just barely over 200 pages and it very succinctly written. It is now my recommended book for Grails beginners.

Tuesday, August 4, 2009

Dealing with Dates: Sorting Legacy Month/Day/Year Dates

Half of my Grails applications use legacy AS400 databases whose tables frequently have dates stored in 6-bytes in MMDDYY format. I map those columns to Date attributes in my domain classes using a custom Hibernate type class (written in Groovy) and everything is hunky-dory -- until I try to sort or filter values on those dates.
The solution is actually quite simple: use HSQL with an algorithm to convert the dates to YYMMDD.

The following looks for contract prices where August 14, 2009 is between the MMDDYY begin and expire dates:


def query =
ContractPrice.executeQuery(
"""FROM ContractPrice cp WHERE
? BETWEEN
MOD((cp.beginDate * 10000.01), 1000000)
AND
MOD((cp.expireDate * 10000.01), 1000000)
""",
[90814],
[max:params.max.toInteger(),
offset:params.offset.toInteger(),
sort:params.sort])


The trick is an old RPG programmers trick of multiplying the MDY date by 10000.01.
Note that the query will be fairly slow as it will have to do a table scan. But what my applications normally do is use precedes the date math with a predicate on a column that performs well with the query optimizer.