Brrr!

I’m working on a contract in an office in a renovated warehouse in downtown Toronto and although it’s not that cold outside (-3 Celsius) the office is so cold I’m warming my hands on my Powerbook power brick.

Brrr!

Buffy Porson

One of the coolest projects I built as a kid was from the book The Buffy-Porson: A Car You Can Build and Drive (see more here). I spent the entire winter when I was 12 building it. The finished car was gloss black and looked very cool. I remember scouring all of the bike shops I could find in Ottawa looking for wire spoke tricycle wheels. I finally found a set of 4 – 12 inch wheels in the basement of some shop on Bank Street (I’m sure all of the shop owners thought I was nuts).

We came back from spending the summer at our cottage that year and someone had broken into our garage and stolen it – I was crushed. I never saw it again.

buffy_porson.jpg

I came across this picture of a finished (and heavily modified version). Makes me want to hunt down a copy of that book and get me a 4×8 sheet of 3/4″ ply. 🙂

Extending EOGenerator templates

The default EOGenerator templates (JavaSourceEOF52.eotemplate and JavaSubclassSourceEOF5.eotemplate) only implement the basic logic in the generated _EO.java and EO.java classes.

I’m assuming you know what eogenerator does, and you understand how the _EO.java and EO.java classes relate to one another. If you don’t, ask, and I’ll try to explain.

For instance, for an entity named Person with the attributes firstName and lastName and a to many relationship to PhoneNumbers named phoneNumbers you’d end up with this:

  • Getter and setter accessor methods for firstName
  • Getter and setter accessor methods for lastName
  • Getter and setter methods for phoneNumbers
  • addTo and removeFrom methods for phoneNumbers

This is about the same amount of java that you’d get from EOModeler if it generated your java for you. Acceptable, but we can do much better.

My Template

My templates (which you can download here) are derived from the advanced sample template that ships with eogenerator (EOGJavaSource.eotemplate) and create the following additional methods in your _EO.java class:

For each to-many relationships

  • addToRelationshipNameRelationship(Object obj) – calls addObjectToBothSidesOfRelationshipWithKey on the relationship with obj
  • removeFromRelationshipNameRelationship(Object obj) – calls removeObjectFromBothSidesOfRelationshipWithKey on the relationship with obj
  • createRelationshipNameRelationship() – creates a new object matching the destination type of the relationship, inserts it into this EO’s EOEditingContexts and adds it to the relationship.
  • deleteRelationshipNameRelationship(Object obj) – removes obj from the relationship and then calls editingContext().deleteObject(obj)
  • deleteAllRelationshipNameRelationships – iterates through all of the objects in the relationship, calling deleteRelationshipNameRelationship.

For each model defined fetch specifications

  • objectsForFetchSpecificationName(EOEditingContext ec, AObject aObjectBinding, BObject bObjectBinding, …) – a static method that returns any objects matching the fetch spec FetchSpecificationName. It takes typed objects for any bindings defined in the fetchSpec.

Using the templates

Using my templates is straight forward, simply specify them when you call EOGenerator (see this post for more details). Before you use my templates however, you will need to specify the name of the class that your EO’s should inherit from (EOGenericRecord is the default). Replace the reference to CBEOBaseClass in the constructor section of CBJavaSourceEOF5.eotemplate (it should be around line 29).

Extending the templates

EOGenerator uses a tool called MiscMerge to create the java class from the EOModel. There is a MiscMerge.rtf included in the eogenerator distribution, but you can figure out what is going on pretty easily just by looking at the templates (the template that does most of the work is CBJavaSourceEOF5.eotemplate).

One of the downsides to using Key Value Coding is that you lose compile time checking on valueForKey methods. For instance, calling:

valueForKey("anAtribute")

will compile fine, but fail at runtime if the attribute is actually called anAttribute.

So, one extension you may wish to make to my templates is to have static strings created to that map to each of your attributes. This means that you can call:

valueForKey(MyEO.AN_ATTRIBUTE)

and the compiler will catch your typos.

The EOGJavaSource.eotemplate included with eogenerator includes an example of how to do this. The template code between line 34 and 39 will create a static string variable for each of your attributes and relationships. Simply copy these lines of code (in between the <$comment … $> and <$comment) and paste them below the constructor in CBJavaSourceEOF5.eotemplate.

EOGenerator is a very powerful tool, it will get you a lot of machine generated (and more importantly machine maintained) code that will make your applications simpler and easier to build. I highly recommend exploring its capabilities a little.