Showing posts with label groovytools. Show all posts
Showing posts with label groovytools. Show all posts

Wednesday, October 22, 2008

UPDATED: Re-visiting MetaBuilder

I previously blogged about a new feature of MetaBuilder that I'm working on allows you to visit each object, as they are built, using a closure. I've updated the functionality so that the build visitor closure is given a CreateNodeEvent instance for each constructed node as follows:

public class CreateNodeEvent {
def name
def node
def parent
def isRoot // set to true, if the new node is a root node
}

If not a root node, the closure should return the node, or possibly a different node, when it is done.

Using a Build Visitor to Build a List of Root Nodes
An example closure that builds a list of all root nodes might be:

{ if(isRoot) { myList << it.node }; it.node }

In fact, I thought that usage might be so common that I included another set of buildList methods that returns a list of root nodes for you.

I'd also thought about exposing the ObjectGraphBuilder.postNodeCompletion() method, but it doesn't give you the node name, which is sometimes useful to have. It also doesn't tell you whether you're dealing with a root node (though you can probably derive that from the fact that parent == null for a root node.)

Using a Build Visitor to Build a Map of Root Nodes
Here's another build visitor example: say I have classes Order and OrderLine as follows and I want to use MetaBuilder to read Orders from a file into a map called orders, keyed on id:

class OrderLine {
def upc
def qty
def price
}

class Order {
def id
def lines = []
}

MetaBuilder mb = new MetaBuilder(getClass().getClassLoader())
mb.define {
order(factory: Order) {
properties {
id(req: true)
}
collections {
lines {
line (factory: OrderLine) {
properties {
upc(req: true)
qty(req: true)
price(req: true)
}
}
}
}
}
}

def orders = [:]
mb.build( { if(it.isRoot) { orders[it.node.id] = it.node }; it.node }, new File("orders.mb").toURL() )
A Hibernate Example
Andres Almiray's recent blog post on using ObjectGraphBuilder to create Grails fixtures inspired this next example, which extends the previous
example to insert each object into a database using Hibernate:

Session session = HibernateUtil.getSessionFactory().getCurrentSession();

session.beginTransaction()

mb.build( { if(it.isRoot) { session.save(it.node) }; it.node }, new File("orders.mb").toURL() )

session.getTransaction().commit()
Final Thoughts
One of the benefits of this feature is that it enables you to process large numbers of build objects without having to incur the overhead of building a list to contain them all.

Friday, September 5, 2008

Catching up!

A lot has happened since my last post: a vacation in France, the start of a new school year for the kids and the first release of a new Groovy utility that I've been working on, MetaBuilder.

MetaBuilder offers a number of features that make creating and using new builders safer and easier. First and foremost, it lets you specify your builder using a simple build language with lots of functionality to validate and control how objects are built.

Here's a Groovy script example to give you the flavor of it:

import groovytools.builder.*

MetaBuilder mb = new MetaBuilder()

mb.define {
customer {
properties {
name(req: true)
age(check: 1..120)
sex(check: ~/M|F/)
}
}
}

def aCustomer = mb.build {
customer(name: 'J. Doe', age: 25, sex: 'M')
}

If you manage to mistype a property name or violate a check constraint, MetaBuilder will throw an exception.

Wednesday, July 9, 2008

Introducing: 'uncaught exceptions'

Welcome to uncaught exceptions wherein I'll be sharing all sorts of things I come across while developing software and some other things, too.

I'm primarily a Java software developer, but I do a lot with Oracle and most recently, Groovy. (If you're a serious Java developer and you haven't seen Groovy yet, head on over there and check it out.)

One of the things that I've been working on for fun is groovytools, a collection of Groovy tools and experiments. The first of which is GPP, a Groovy port of VPP, which is an Ant and Velocity-based preprocessor. Either GPP or VPP can be a useful for code generation, mail-merge and numerous other template-based tasks. In general, I find Groovy much more convenient and less quirky to use than the venerable Velocity. In fact, the port to Groovy was extremely smooth and since then I haven't used Velocity again.

My advice to all programmers just getting started:
while(true) {
try { ... }
catch (Exception e) { ... }
}

For everyone else, never give up, just keep trying!
Content © didge

About Me

didge is my professional nickname, it's short for digital dave
Powered By Blogger