text: In a recent interview, Groovy Project Manager Guillaume Laforge mentioned that his favorite Groovy feature is its implementation of the Meta Object Protocol, or MOP. This protocol enables an object to make specific choices that affect its own state or behavior when methods, or messages, are passed to it at runtime. As described by the PARC Software Design Area projects homepage (see Resources):
  The metaobject protocol approach ... is based on the idea that one can and should open languages up, allowing users to adjust the design and implementation to suit their particular needs. In other words, users are encouraged to participate in the language design process.
  Clearly, this broad-mindedness suggests some exciting possibilities for building smarter applications, and even languages. In this month's column, I'll show you how Groovy implements MOP, and then use a working example to introduce you to one of its most exciting practical applications: a dictionary app that functions as a mini-language!
  You'll find the source code for the dictionary application example in the Download section. See Resources to download DbUnit, which you will need to follow the example.
  The Meta Object Protocol is not unique to Groovy, nor was it invented by Groovy's makers. In fact, it can trace its lineage to LISP and to some of the people behind AOP. Given that lineage, it shouldn't be a surprise to find MOP embraced by the cosmopolitan creators of Groovy.
  A MOP implementation is possible in Groovy because every object in Groovyland implicitly implements
  groovy.lang.GroovyObject, which defines two methods dubbed
  invokeMethod() and
  getProperty(). At runtime, if a message is passed to an object that doesn't exist as a property or method defined in the class or its hierarchy,
  getProperty() or
  invokeMethod() is called.
  In Listing 1, I've defined the Groovy class
  MOPHandler, which implements
  invokeMethod() and
  getProperty(). Once I've created an instance of
  MOPHandler, I can call any number of methods or properties and watch as it prints out messages explaining what was invoked.
  Listing 1. MOP gets a handle on invocation
  Go ahead, run the code from Listing 1 and you'll see the output shown in Listing 2.
  Listing 2. You didn't believe me, did you?
  Pretty slick, isn't it? MOP works well as a safety net to catch message passing errors, but that's not its most interesting function. The virtues of MOP come to light when you use it to create smart objects that can intelligently respond in a generic fashion to any message passed to them.
  One of the interesting things you can do with MOP is create pseudo-domain-specific languages, or mini-languages. These are unique languages targeted at solving specific problems. Unlike prevailing languages such as Java, C#, or even Groovy, which are considered generic languages applicable for any problem, mini-languages fill niches. Need an example? Consider Unix with it's venerable shells like Bash.
  Just for fun -- and so you can really get a handle on MOP -- I'll spend the rest of this column creating a dictionary application that is actually its own mini-language. The application will provide an interface for querying a dictionary. It will allow users to create new word entries, obtain the definition of a given word, obtain synonyms of a given word, query for a word's part of speech, and remove words. Table 1 summarizes this mini-language.
  Table 1. Semantics of the dictionary mini-language
  The dictionary application
  The dictionary application will sit on a database with the table structure shown in Figure 1. If you're a regular reader, you may recognize the table structure from the column "Mark it up with Groovy Builders."
  Figure 1. Simple database model for a dictionary
  Note: I'm going to ignore
  definition's
  EXAMPLE_SENTENCE column.
  I'll create a simple facade that will serve as the interface between the user and the database. The facade will utilize Groovy's MOP features by providing implementations of
  invokeMethod and
  getProperty. The
  invokeMethod method will determine the command and delegate responsibility to the corresponding internal
  private method.
  Because the application will rely on a database, you may want to refresh your memory of GroovySql before going further. I'll also be using Groovy's regular expressions (introduced in Feeling Groovy) to determine the messages passed to the facade.
  I'll test the facade with Groovy as I write it, so you may want to review Groovy's unit testing abilities, which I covered in "Unit test your Java code faster with Groovy."
  Finally, I'll use DbUnit to manage the state of the database throughout testing. Since I've never written about DbUnit in this series, I'll give you a little primer on using DbUnit with Groovy before going on.
  DbUnit is a JUnit extension that places your database into a known state between test runs. Using DbUnit within Groovy is amazingly simple because DbUnit offers an API that allows for delegation within a test case. To use DbUnit, I need to provide it with a database connection and a file containing the data I'd like the database seeded with. Once I plug these into JUnit's fixture mechanism (that is,
  setUp()), I'm good to go!
  Listing 3 shows the dictionary application's beginning test class.
  Listing 3. Dictionary application's beginning test class
  In Listing 3 I've created the class shell that will serve as my test class as I write the dictionary application. When a test is invoked, JUnit will call
  setUp(), which will then call DbUnit's API. DbUnit will insert the data found in the file test/conf/words-seed.xml into the database. The contents of the file test/conf/words-seed.xml can be seen in Listing 4.
  Listing 4. Sample seed file
  The seed file's XML elements (shown in Listing 4) match table names. The element's attributes match corresponding table columns.
  Now that I have my test class defined I can start developing (and testing) the application. I'll tackle each feature in the order listed in Table 1.
  If a user wants to query the part of speech for a word, he or she can pass in a message that looks something like
  isRowelAVerb, or
  isEstivalAnAdjective. (Note that I'm following camel-case semantics and trying to obey proper English by allowing both
  a and
  an.) The intelligent logic for answering the question becomes a matter of determining the proper word, which in the first case is Rowel and in the second is Estival. The part of speech has to be determined too, which in the examples would be Verb and Adjective, respectively.
  The logic becomes trivial when you put regular expressions into action. The pattern becomes
  is(.*)(An|A)(Verb|Adjective|Adverb|Noun). I'm only interested in the first and third groups (the word and the part of speech). Given those, I can write a simple database query that retrieves the part of speech and compares the question with the answer, as shown in Listing 5.
  Listing 5. Determining the part of speech
  Listing 5 looks pretty simple, but let's see what happens when I write a few test cases for it.
  Listing 6. Testing the determination of a word's part of speech
  Look again at the XML in Listing 4. Because I'm relying on DbUnit to put the database into a known state before any tests are run, I can assume that the word, pugnacious, is valid with its part of speech set to Adjective. In Listing 6, I add two simple tests to
  DictionaryTest (see Listing 3) that ensure the logic works correctly.
  The semantics for querying synonyms has the following pattern:
  synonymsOfBloviate where the desired word (Bloviate) follows
  synonymsOf. The regular expression is even easier:
  (synonymsOf)(.*). Once the desired word has been found, the logic involves a database query, which joins the
  word and
  synonym tables. The returned synonyms are added to a
  List and returned as shown in Listing 7.
  Listing 7. getSynonyms implementation
  The tests shown in Listing 8 verify that a word defined with synonyms returns them correctly, and also that one without any synonyms (Rowel) returns an empty
  List.
  Listing 8. Don't forget to test that method!
  The remove logic in Listing 9 is flexible, because I allow the command to be
  remove or
  delete followed by the word. For example,
  removeGlib and
  deleteGlib are both valid commands. The regular expression therefore becomes:
  (remove|delete)(.*) and the logic is an SQL
  delete.
  Listing 9. Delete or remove a word
  Of course, being so flexible means that I must write at least two test cases for removing a word, as shown in Listing 10. To verify the words are truly gone, I attempt to retrieve their definitions (see 5. Retrieving a word's definition for more information) and confirm that nothing comes back.
  Listing 10. Test both cases
  The semantics for creating a new word is a message that doesn't match any query patterns and which contains a parameter list. For example, a message like
  echelon("Noun", ["a level within an organization"]) matches this pattern. The word is echelon and the first parameter is the part of speech, followed by a
  List containing definitions and an optional third parameter, which can be a
  List of synonyms.
  As demonstrated in Listing 11, creating a new word in the database becomes a matter of inserting the word and its definition in the proper tables (
  word and
  definition); furthermore, if a
  List of synonyms is present, each one is added.
  Listing 11. Creating a word
  In Listing 11, the primary key logic is dangerously simple; I can boost my confidence with a few tests, though.
  Listing 12. Test cases for the create-word logic
  As usual, I write a few test cases in Listing 12 to verify things work as expected. After creating a word, I query the
  dictionary instance for the same word to confirm it made it into the database.
  5. Retrieving a word's definition
  Any message passed to the dictionary application that doesn't match any of the previous query types (part of speech and synonym) and which doesn't contain any parameters, is assumed to be a definition query. For example, a message like
  .glib or
  .glib() would return glib's definitions.
  Listing 13. Finding a word's definitions isn't so hard!
  Because I allow both a method call and a property call to work as a definition query, I must write at least two tests in Listing 14. Just like in Listing 6, I can assume pugnacious is already in the database. Isn't DbUnit handy?
  Listing 14. Test both cases -- method call and property
  And that's it for the semantics of the dictionary application. Now let's have a deeper look at the logic underlying the application.
  The meat of the dictionary application lies in my implementations of
  invokeMethod and
  getProperty.
  In these methods I need to make intelligent decisions on how to proceed when a message is passed to the application. The decisions are found in a series of conditional statements, which execute
  String operations to determine the type of message.
  The only vexing conditional in Listing 15 happens to be the first one, which attempts to verify if the message is truly a definition query and not one of the other possible combinations such as
  is...,
  remove...,
  delete..., or
  synonymOf....
  Listing 15. The logical heart of MOP
  The
  isGetDefinitions method does a fair bit of work and relies on the
  isRemoveDeleteIs to do some of it. Once it's been determined that a message doesn't fit the definition query, the logic becomes much simpler.
  The
  getProperty method in Listing 16 is simple since I've stipulated that users can only query for definitions by properties and nothing else; consequently, I call the
  getDefinitions method when
  getProperty is invoked.
  Listing 16. Properties are easy, thankfully!
  And that's it! Really.The logic found in Listings 5 through 16 creates an application that bestows a fair bit of flexibility to users with an overall complexity hit that isn't all that bad. As noted previously, of course, the primary key logic found in the application isn't bulletproof. Myriad steps could be taken to improve this aspect, from database sequences to a framework like Hibernate, which handles IDs quite elegantly.
  Seeing is believing, so Listing 17 demonstrates the dictionary application's language in full force. (If only I'd had something like this before taking the SATs!)
  Listing 17. The Dictionary show
  At this point, you may be wondering what's the point? I could just have easily exposed those
  private methods, rearranged a few things, and offered an application that behaved normally (that is, I could have exposed a
  getDefinition method, a
  createWord method, etc.) without using MOC.
  Let's examine this proposition -- say I want to create the exact same dictionary application without relying on Groovy's MOC implementation. I'd have to redefine the parameter list for the
  createWord() method to look something like
  def createWord(word, partOfSpeech, defs, syns=[]){}.
  So as you can see, my first step would be to drop the
  private modifier and replace it with
  def, which is the same as declaring the method as
  public. Next, I'd define the parameters and make the last one optional (
  syns=[]).
  I'd also have to define a
  delete method that would, at minimum, call the
  remove method to support both removes and deletes. The part-of-speech query would also have to be altered. I could add another parameter, so it would possibly look something like
  determinePartOfSpeech(word, partOfSpeech).
  In essence, with the above steps I would have shifted the dictionary application's conceptual complexity from the MOP implementation to my static API. Which begs the question -- what would be the point of doing that? Surely you can see that by implementing MOP I've opened up unparalleled flexibility to my application users. The resulting API isn't so much a series of statically defined methods as a flexible language in itself!
  If you think your head is spinning now, think about this: What if you could build the dictionary application to allow users to create queries at will? For instance,
  findAllWordsLikeGlib or
  findAllWordsWithSynonymGlib, and so on -- these semantics become simply a matter of text-parsing on the MOP side and a gold mine of queries on the user's side!
  Now think a little more: What if you could create another mini-language that was a bit more useful in a business sense -- like a mini-language targeting stock trading? What if you went further and built this application to be console friendly? Rather than writing scripts, users would use Groovy's shell. (Remember what I said about Bash?)
  If you think this is kind of alchemic utility is for esoteric LISP guys drooling over Emacs extensions, think again! You need only look across the street at those vociferous Ruby on Rails gurus to know why that platform is so exciting. Peek under the hood and you'll see MOP at work, allowing you to create nifty queries without having to drop down into SQL, if you follow a naming pattern. Now who's drooling?
  Information about download methods
  Learn
  - "Fast-track your Web apps with Ruby on Rails" (David Mertz, developerWorks, June 2005): What gives Ruby on Rails its dynamic flexibility? MOP, in part.
  - "Control your test-environment with DbUnit and Anthill" (Philippe Girolami, developerWorks, February 2004): More on test-driven development with DbUnit.
  - "AOP banishes the tight-coupling blues" (Andrew Glover, developerWorks, February 2004): A primer on aspect-oriented programming.
  - The SDA Projects page: A listing of PARC's software design projects, including AspectJ and MOP.
  - The Practically Groovy series page: Tips and tricks for Groovy programmers.
  - The Java technology zone: Hundreds of articles about every aspect of Java programming.
  Get products and technologies
  - The Groovy project page: Download Groovy.
  Discuss
  - developerWorks blogs: Get involved in the developerWorks community!
  .