Today I kicked off a small consulting engagement with a client that is looking to productionise a prototype web application written with a mainstream Java web framework. Boy, what an eye opener! For the most part the application has been written well, but there is just so much of it. The scope of this application is lower than the Grails projects I have worked on, but the volume of code is grossly disproportionate. Thinking that this doesnt quite seem right I tried to apply some basic refactoring to the code, but soon gave up because I was just massaging valid application code. It honestly just seems to take a lot more Java code to get things done. I really am not wanting to unleash to much negativity on Java here, after all Java is within Groovys DNA. But I was just really surprised by the immediate contrast I noticed when switching back to Java after a sustained period of Groovy coding.
Monday, February 22, 2010
You dont know how lucky you are
Today I kicked off a small consulting engagement with a client that is looking to productionise a prototype web application written with a mainstream Java web framework. Boy, what an eye opener! For the most part the application has been written well, but there is just so much of it. The scope of this application is lower than the Grails projects I have worked on, but the volume of code is grossly disproportionate. Thinking that this doesnt quite seem right I tried to apply some basic refactoring to the code, but soon gave up because I was just massaging valid application code. It honestly just seems to take a lot more Java code to get things done. I really am not wanting to unleash to much negativity on Java here, after all Java is within Groovys DNA. But I was just really surprised by the immediate contrast I noticed when switching back to Java after a sustained period of Groovy coding.
Tuesday, February 16, 2010
Pre-compiled GSP's
Its nice to see that GSP's are now pre-compiled in WAR file builds as of Grails version 1.2. This means that Grails is now less permgen space hungry. Your standard Java opts parameters should now work fine.
Monday, February 15, 2010
Accessing Grails domain constraints at runtime
class User {
String username
String passwd
static constraints = {
username(blank:false, unique: true)
passwd(blank:false, minSize:7)
}
}
The above domain class defines a "User" that contains a user name and password. The user name must not be blank and must be unique. The password must not be blank and must be a minimum of 7 characters in length.I recently stumbled upon a use case where I was required to automatically generate a password, and of course this password needed to conform to the validation constraints defined in the "User" domain class. I didn't want to hard code the minimum size of the password because there is always a chance it will change in the future. What I needed was a way to obtain the "minSize" constraint value of the "passwd" property.
Here is how I did it
def constrainedProperty = User.constraints.passwd
def minSizeConstraint = constrainedProperty.getAppliedConstraint('minSize')
def length = minSizeConstraint.getMinSize()
The above code snippet first obtains an instance of org.codehaus.groovy.grails.validation.ConstrainedProperty which is an under the hood class that provides the ability to set constraints against a property of a domain class (in this case "user.passwd"). I then call the "ConstrainedProperty" instance to get the applied constraint of "minSize" which then returns an instance of org.codehaus.groovy.grails.validation.MinSizeConstraint. The "MinSizeConstraint" class is the class that is charged with performing the actual validation of the "minSize" constraint, and so therefore also contains the value of the minimum size of the "passwd" field I am concerned with. I can now easily generate a password that is greater in length than the "length" variable, currently 7.Easy peasy
Sunday, February 14, 2010
Grails partial validation of domain objects
I am developing a web flow application that will populate a domain object (the user is filling in an application form) across multiple controllers and or actions. At each stage of the flow I am wanting to only validate the properties which the current action is charged with binding.
Lets say this is my domain object
class Application {
String firstName
String lastName
String emailAddress
Date dateOfBirth
String sex
String address1
String address2
String address3
String address4
//etc..
static constraints = {
firstName(blank:true)
lastName(blank:true)
emailAddress(email:true)
dateOfBirth(nullable:false)
sex(inList:["Male", "Female"])
address1(blank:false)
address2(blank:false)
address3(blank:false)
address4(blank:false)
}
}
I would like to populate this domain across three controller actions. To do this I just need to pass a map of property names to the "validate" method of the domain object. Yep, its as simple as that!//...action1
applicationInstance.validate(['firstName', 'lastName', 'emailAddress'])
//...action2
applicationInstance.validate(['dateOfBirth', 'sex'])
//...action3
applicationInstance.validate(['address1', 'address2', 'address3', 'address4'])
Accessing Grails application properties (metadata)
A Grails application.properties file contains meta type information about your grails application. This file is user editable and should only be used for declaring metadata that describes your application. Do not store configuration information in this file.
There are two ways to access the metadata contained within this file.
Accessing from GSP:
There is a GSP tag within the standard Grails tag library that allows access to this metadata, and surprise surprise its called g:meta.
<g:meta name="app.grails.version"/>
The above tag will render the version of the Grails Framework that is expected by your application.Accessing from application code:
There is a very useful class within the Grails commons package called GrailsApplication. An instance of this class is automatically wired into Grails controllers and can be referenced from the following variable.
grailsApplication
If you wish to access the GrailsApplication instance outside of a controller you will need to do as follows.import org.codehaus.groovy.grails.commons.ApplicationHolder
...
def grailsApplication = ApplicationHolder.application
Once you have access to the GrailsApplication instance you can then reference the application metadata as follows.//Print application version
println grailsApplication.metadata.'app.version'
//Print application name
println grailsApplication.metadata.'app.name'
//Print expected Grails version
println grailsApplication.metadata.'app.grails.version'