Wednesday, October 12, 2011

Loading files in Grails without application context

Like all Grails n00bs, I got into a pattern of loading a bunch of data into the DB in Bootstrap.groovy, a la




def init = { servletContext ->
println "starting"
if(!Role.list())
{
setupRoles()
}
println "roles set up"
if(!Person.list())
{
setupPersons()
}
println "people set up"
if(!Organization.list())
{
setupWorkgroups()
}
println "orgs set up"
if(!Customer.list())
{
setupCustomers()
}
println "customers set up"
if(!Project.list())
{
setupProjects()
}
println "projects set up"
if(!Milestone.list())
{
setupMilestones()
}
println "milestones set up"
if(!UserDefaultMilestone.list())
{
setupDefaultMilestones()
}
println "default milestones set up"
if(!OrgGoals.list())
{
setupOrgGoals()
}
println "goals set up"
if(!IMBO.list())
{
setupIMBOs()
}
println "imbos set up"
}


Eventually something inside said that 800 line Bootstraps were a bad idea (reading Robert Martin's Clean Code is having an effect.) I decided to abstract that away with the Strategy Pattern:





public interface CreationAlgorithm {
void loadData();
}

import edu.asu.engineeringed.Media
import org.codehaus.groovy.grails.commons.ApplicationHolder

class MediaCreation implements CreationAlgorithm {
public static void loadData(){
createMedia()
}

private static final void createMedia() {
def media =
[
"awesome" : [
name:"Awesome",
description: "This picture should make you smile",
fileName:"images/awesome.png"
]
]

media.each { k, v ->
def grailsApplication = ApplicationHolder.application
def resource = grailsApplication.mainContext.getResourceByPath(v.fileName)
def theFile = resource.file
def newMedia = new Media(fileData:theFile.readBytes(),
name:v.name,
description:v.description)
newMedia.save()
}
}
}

import ProfessorCreation
import PresentationCreation
import UserCreation
import BasicCreation
import CourseCreation
import ResearchCreation

class BootStrap {
def init = { servletContext ->
BasicCreation.loadData()
ProfessorCreation.loadData()
PresentationCreation.loadData()
CourseCreation.loadData()
UserCreation.loadData()
ResearchCreation.loadData()
MediaCreation.loadData()
AccomplishmentCreation.loadData()
}
def destroy = {
}
}



The MediaCreation bit was an interesting case. I read this post, but didn't like the approach of putting my files in the grails-app/conf directory or that I had to do it in Bootstrap.



I didn't wanna pass the Grails servletContext to that one as it would break the consistency (eventually I'll refactor it down to using the Groovy Spaceship operator on a map of interface instances or do some metaprogramming magic), so I had to figure out how to get the grailsApplication in a Groovy src/ class file. This showed me the way, and since Spring WebApplicationContext offers an interface for Resources it made the code nice and clean.

No comments:

Post a Comment