SpringOne2GX, Day 3 Recap

Two great demos in the morning regarding Gradle, by it’s author, Hans Docktor. Gradle is something I’d heard about frequently, but never bothered to look into thinking that I didn’t need to learn another way to build until it was necessary. Combining the declarative nature of a DSL with the scripting capabilities of Groovy, Gradle looks to be a “next generation” build tool. Familiar constructs exist – job, task, etc – but each of those constructs has properties that can be inspected, and the DSL itself can be easily extended to meet an organization’s need. Since the Ant jars are packed with Gradle, it looks like Gradle should have easier inroads into the enterprise than other new build technologies. Any task or all of the build can be written using Gradle, which would allow for a migration approach as opposed to a conversion. The demos themselves were smooth and engaging with no technical hiccups. Really good stuff.

The last talk of the conference was a demo of Daisy CMS Grails. Like a few other talks/demos, I learned more about the subject itself (CMSs) rather than the technology that was the subject of the talk.

In all, a good conference. The quality of content in the talks varied greatly. Some were demos, some were presentations, and others seemed like they were thrown together at the last minute. The good content was great, and the not-so-good content, well, was not-so-good. Although I’m sure the pub crawl was fun, I think the conference could have fit into two days had the lower quality material been removed. I came away with a few exciting things to look into and a new appreciation for the Spring/Groovy community.

SpringOne2GX, Day 1 Recap

It was an interesting day today at SpringOne2GX. There were many interesting presentations – here’s some thoughts on the 5 I attended today:

Guillaume Laforge’s talk on Gaelyk first thing in the morning was very interesting. I’ve been casually following the Gaelyk project for a while and was happy to hear more about it from the project’s founder. It looks like a great toolkit to easily take advantage of all of the features of the Google App Engine using a familiar and concise language in Groovy. A nice departure from Grails, Gaelyk is packed with a lot of interesting options and flexibility being on the Google App Engine. Definitely worth checking out for lightweight web apps with simple persistence needs.

Arjen Poutsma’s talk on the new features of Spring-WS was interesting also – good to see the familiar patterns and usages of Spring MVC making their way into the integration side. I’m currently on a Spring 3 project, and I’m quite sure there’s a compelling reason to roll this in. Definitely looking forward to getting into the details.

The Spring Roo presentation by Rod Johnson was a real eye-opener and definitely renewed my interest in the static-typed side of the Spring ecosystem. Grails, for straight java – what a cool idea. Pseudo-dynamic, clean code with boilerplate code woven in using AspectJ ‘side files’. I can’t wait to fire this one up, although I’m skeptical about how well I will work with it outside of eclipse/STS, which is not my first choice in regards to an IDE. The scaffolded UIs look very impressive. Looking forward to learning more about Roo + GWT tomorrow.

Another interesting Groovy-related talk was by Guillaume Laforge and Paul King on building DSLs with Groovy. A few very cool tricks and what I’m sure will be useful strategies for building DSLs using Groovy.

Wrapped up the day checking on the Grails 1.3 update with Graeme Rocher. Definitely a lot of stuff coming up that will be useful as the framework continues to grow. The GORM implementations at tonight’s keynote were awesome. New dependency management will be nice and clear with the right amount of control.

Looking forward to tomorrow!

Just call me Casey Jones

I’ve recently found myself involved in some RoR work. It took a bit to take my java blinders off, but since they’ve been off, the work has been great. With past Grails experience in mind, here are a few first observations after a couple of weeks of being a Rails dev under my belt.

I like migrations
I used to think I liked the “declare everything in the model” style of defining models in grails, but since then I’ve come to appreciate having to write migrations for the (dare I say?) discipline they force upon the author. Writing those migrations makes me think carefully about how the model change I’m trying to make impacts what’s already in the database.

Plugin/gem maturity
The community is strong – there are far more useful plugins/gems available for RoR apps than there are for Grails apps. You get just a few key choices in a Grails app. With an RoR app, and this sometimes can be cause for concern, there are many plugins to choose from – authorization and authentication gems are a good example. There are basically two choices in Grails – Spring Security and JSecurity. There are many choices for RoR apps, and further, they can be mixed and matched with the authorization and authentication components being separate.

Railscasts
So useful. I’d like to have the option of choosing a celebrity voice-over for them, though. Homer Simpson and/or Snoop Dogg would be my choices. http://railscasts.com/

The learning curve
Groovy & Grails has a definite advantage in being easier to pick up for someone with a java background. I think this is also a downfall of groovy/grails, because it is so easy to fall back to java instead of learning a new (or more efficient) way to solve a problem (ie with a new language and framework a la RoR).

The enterprise and it’s architects
Code that runs on hardware they’ve already got, that leverages existing resources (people and hardware), and is at least somewhat familiar to them is appealing. RoR is not this.

C to tha I
If I can’t roll a build and have Chuck Norris give me the thumbs up afterwards, I am somehow not satisfied. Autotest, rspec, and growl can get me by in the meantime.

… I just wrote a rake task. I’ll write about that later.

I hope this keeps happening.

Now that my first Groovy/Grails project has wrapped up, I thought I’d share some things I learned. I am a big fan of the framework, which is a somewhat biased opinion, mostly given my background as a java developer. Things that I already knew and appreciated were made easier to use. That’s usually a good thing…

Scaffolding is cool, but…
The scaffolded code contains good examples, but scaffolding is not all that useful in the real world, save for very specific cases – mostly admin functions.

Drink the kool-aid.
Language and framework features can really save you a lot of time in writing clear and concise code. Remembering to use them is the trick. Keep your Refcardz handy. Don’t fight the framework. Keep it simple.

It doesn’t have to be a closure.
I found exceptions thrown from closures to be hard to trace. Just my opinion.

Don’t forget your past.
This is the greatness of the things you know (Spring, Struts 2, Spring MVC, Hibernate), minus all the xml. You’ll spend a lot more time writing code instead of configuring. You’re not going to want to go back, unless you have to of course.

This is still new.
Even though it’s been around for a few years, the framework still has bugs, and can still change in some pretty big ways from release to release. The cutting edge is cool. Be careful.

Plugging in?
Just because it’s in the plugin directory doesn’t mean it works. With the previous item in mind, and given the fact that the community is still growing, there are a lot of plugins available that are written for a specific version of Grails. Again, be careful.

Protecting Parameters in Groovy/Grails

Section 11.2 of the Grails Framework Reference Docs talks about how to protect parameters in a Groovy/Grails app. On my current project, on public facing pages, we’ve been obscuring ids using the base64 codec that comes with grails. Here is a quick example:


def encodedString = "test".encodeAsBase64()

println encodedString

//build your decoded string from the byte array returned from the decode method.
def decodedString = new String(encodedString.decodeBase64())

println decodedString

Obscure ids and keep those urls hard to guess!

Shiro/Grails Tips

The Shiro plugin page in the Grails plugin repository has great information. Here are a couple of additional items I picked up during an implementation on my current project:

1. Filter every action except ‘x’ on a given controller

	    myFilter(uri: '/myController/**') {
	      before = {
	        if (!controllerName || actionName == "anOpenAction" || actionName == "anotherOpenAction") return true

	        // Access control by convention.
	        if (!isErrorPage(controllerName, actionName)) {
	          accessControl()
	        }
	      }
	    }

In this case, we’re taking advantage of common properties in grails. Basically, we’re filtering actions on myController. The first ‘if’ clause (!controllerName) filters for direct/default controller views, ignoring direct views. The other clauses are saying ‘if we’ve hit this filter, but the actionName is ‘anOpenAction’ or ‘anotherOpenAction’, let the request through.

2. Simple landing pages – enhancing the ‘free’ Shiro AuthController

If there is no target URI on the user’s original request to login, meaning, if they weren’t challenged and instead clicked on a ‘login’ link, a simple way to control where they are directed (assuming the goal is not to direct them to ‘/’) is as simple as this (with source from the AuthController):

	// If the user came to the login page via redirect (security filter caught an attempt to
	            // go to a restricted area of the site), then send them back from whence they came.
		        def savedRequest = WebUtils.getSavedRequest(request)
		        if (savedRequest) {
		            targetUri = savedRequest.requestURI - request.contextPath
		            if (savedRequest.queryString) targetUri = targetUri + '?' + savedRequest.queryString
		            println "Target URI, from saved request: ${targetUri}"
		        }
		        else {
		            // If a controller redirected to this page, redirect back
			        // to it. Otherwise redirect to an appropriate URI depending on the
		            // role of the user who just logged in.
		        	if(params.targetUri) {
		        		targetUri = params.targetUri
		        	}
		        	else {
		        		targetUri = //some bit of code that determine the URI from the current user, etc.
		        	}
		        }

Where that last reference of ‘targetUri’ is somehow set to where you want your newly-authenticated user to land.

Strange Days, Indeed

On my current project, I was adding a closure to a taglib that displayed a link conditionally, based on the current logged-in user’s role. The taglib is referenced on every page of the application, as it is included in the main Sitemesh layout. For the purpose of this example, a user cannot have both of the roles mentioned below.

Originally, the code looked something like this:

	def user = User.findByUsername(SecurityUtils?.getSubject()?.getPrincipal())
	def roles = user?.roles
	roles.each { role->
		if(role.name == RoleNames.CUSTOMER) {
			out << " | ${link(controller:'customer', action:'showProfile'){'View Profile'}}"
			return
		}
		else if (role.name == RoleNames.SALES){
			out << " | ${link(controller:'agent', action:'showProfile'){'View Profile'}}"
			return
		}
	}

The first issue I ran into was a LazyInitializationException while attempting to use the each closure on my list of roles. Apparently, there was a JIRA opened about this.

Since the taglib is part of the Sitemesh layout, it doesn’t keep the hibernate session alive long enough to provide support for lazy fetching of child objects. This is easily overcome with some eager fetching of the child objects – this case, roles.

Now, the code has turned into something like this:

	def user = User.createCriteria().list() {
		and {
			eq('username',SecurityUtils?.getSubject()?.getPrincipal())
		}
		fetchMode('roles', FM.EAGER)
	}

Obvious problem here – I’m expected a single result, but I’m using ‘list()’ instead of ‘get()’. Sorry. It took a minute to figure out. I’m using ‘list()’, I’ve learned my lesson, I’m getting back a result set, and it’s going to be some sort of a list. In other instances I’ve done the same thing, and since the result is not statically typed, I’m expecting I’ll just get whatever the first result is.

Simple enough.

But, something else happened here. In the each closure on roles, ‘role’ was also being interpreted as a list. The code above was failing.

It seems that when you’re eager fetching using ‘list()’, the parent object and all the children (even the singular instances accessed in the each closure) are treated as lists. To function correctly, the code had to be changed to this:

	roles.each { role->
		if(role[0].name == RoleNames.CUSTOMER) {
			out << " | ${link(controller:'customer', action:'showProfile'){'View Profile'}}"
			return
		}
		else if (role[0].name == RoleNames.SALES){
			out << " | ${link(controller:'agent', action:'showProfile'){'View Profile'}}"
			return
		}
	}

That doesn’t seem as clear to me as it could be. A brief conversation with some co-workers, and changing:

		def user = User.createCriteria().list() {

to:

		def user = User.createCriteria().get() {

got things back to normal for us. The comparisons then became:

	if(role.name == ... 

If anyone else has had a similar experience to the one above or an explanation of this behavior, I’d like to hear about it!

Simple Grails Zip Code Custom Validator

My next post was going to be as verbose as the last, and on an equally obscure topic. Instead of two boring posts in a row, I give you this. It’s simple, but it’s useful:


	zip(nullable:false, blank:false,validator:{zip, address ->
		if(zip ==~ /^(\d{5}-\d{4})|(\d{5})$/) {
			return true
		}
		else {
			return "invalidZipFormat" 
		}
	})
		

For the Regex-challenged (which I am), it’s basically saying 5 digits, a dash, followed by 4 digits OR 5 digits and nothing else. Take care of the rest of the formatting on the client side.

Simple, but a good trick for the bag.

Pdf Generation Using Jasper In A Grails App

The jasper reporting engine provides a free, open source tool for report generation in java. It can produce reports in a variety of formats, including pdf, which makes it very handy in creating all types of data filled documents. Suppose you had a report you just finished constructing and wanted to integrate with your latest Groovy/Grails application. There is a grails plugin that provides tools for displaying your report within a page and also nice looking links to download your report in various formats. Depending on the size of your report, this may be the best option. If your report is small, you may also choose to stream the contents of your report back to the browser window. This is particularly nice if you’d like the pdf to display in the browser’s window as if it were a direct link to the file, using the browser’s pdf plugin. If your goal is the latter, here’s how, utilizing the jasper reporting engine, and some of the conveniences of groovy and grails.

1. Get your report ready to be integrated into your application.

A few things to note here – the most important of which is getting your .jasper files onto the classpath of your application after it is built. For this, place your files under ‘%APPLICATION_DIR%/src/java’, where APPLICATION_DIR refers to the root of your grails project. I would recommend creating a ‘resources’ folder in that location, and possibly sub-directors based on your application’s needs. I had a fun time with this particular detail – that’s for another post…

2. Get your data into your report

These small reports are sometimes easiest generated using the XML datasource feature of jasper. This provides the ability to easily test your code and layout offline, as well as flexibility, if your domain model is significantly different than what you’d like to include in your report.

I’ll skip the XML generation. The code below assumes your XML has been provided as a String.

		import org.apache.commons.io.IOUtils 
		import net.sf.jasperreports.engine.JasperFillManager 
		import net.sf.jasperreports.engine.JasperPrint 
		import net.sf.jasperreports.engine.data.JRXmlDataSource 
		import net.sf.jasperreports.engine.JRException 
		import net.sf.jasperreports.engine.JasperExportManager
		
		private byte[] getJasperReport(String xml, String reportName) throws JRException {
			//add any properties you need passed to your report here.
			HashMap hm = new HashMap();
			
			//convert your xml and .jasper file to input streams.  Commons IO provides a nice way to do this.
			InputStream xmlStream = IOUtils.toInputStream(xml)
			InputStream reportStream = this.getClass().getClassLoader().getResourceAsStream(reportName)
			
			byte[] byteArray = null
			JRXmlDataSource jrxmlds = new JRXmlDataSource(xmlStream);
			JasperPrint jasperPrint = JasperFillManager.fillReport(reportStream, hm, jrxmlds);
			byteArray = JasperExportManager.exportReportToPdf(jasperPrint); 
			
			//this is your report, available as a byte array.  
			return byteArray		
		}

3. Get those bytes back to the browser.

Here, we’ll stream the bytes back to the browser. Since this report is ‘small’, we’ll configure the cache settings accordingly. This code belongs in a controller, as we’ll be dealing directly with the servlet response. pre-check & post-check sets how often (in seconds) the cached object should be checked for freshness before and after it is shown to the user. must-revalidate specifies that the cached object requires revalidation before access. Given the settings below, basically, we’re never going to get this object from the cache. You may choose to configure your caching differently.

	def generatePdf = {
		try {
			//generate or retrieve your XML
			String xml = thisMethodShouldReturnXml()
		
			byte[] bytes = getJasperReport(xml, 'thePath/andNameOfYourReport.jasper')
		
			//get the output stream from the common property 'response'
			ServletOutputStream servletOutputStream = response.outputStream

			//set the byte content on the response. This determines what is shown in your browser window.		
			response.setContentType('application/pdf')
			response.setContentLength(bytes.length)
		
			response.setHeader('Content-disposition', 'inline; filename=quote.pdf')
			response.setHeader('Expires', '0');
			response.setHeader('Cache-Control', 'must-revalidate, post-check=0, pre-check=0');
			servletOutputStream << bytes
		}
		catch(Exception e) {
			//deal with your exception here
			e.printStackTrace()
			//redirect, etc
		}
	}

The servlet response is available as a common property to any controller – a convenience feature of grails. Note groovy’s handling of pushing the report bytes onto the output stream. Also note the lack of calls to ‘flush’ and ‘close’ on the stream. Both conveniences added by groovy.

Depending on your browser, and whether or not that browser has pdf-handling features (via a plugin
or otherwise), you may see different results. A browser with pdf-handling features will render the pdf directly in the browser. If no pdf-handling capability is present, the user is prompted to download or open the rendered pdf, and is provided with the filename specified in the response header. If the user is prompted to download, the page from which the request for the pdf was issued will remain in the browser window.