Elvis carried away by spaceships

I love teaching Groovy to existing Java developers, because they have such a hard time holding back Tears Of Joy when they see how much easier life can be. Today, though, I did a quick demo that resulted in a line of Groovy that was so amusing I had to post it here.

Consider a trivial POGO (Plain Old Groovy Object) called Course:

class Course
    String name
    int days
    String toString() { "($name,$days)" }
}

The goal was to take a collection of courses and sort it by the number of days. That’s really easy in Groovy:

def courses = [
    new Course(name:'Groovy',days:4),
    new Course(name:'Grails',days:3),
    new Course(name:'Spring',days:4),
    new Course(name:'Hibernate',days:3)
]

assert courses.toString() == '[(Groovy,4), (Grails,3), (Spring,4), (Hibernate,3)]'

courses.sort { it.days }

assert courses*.days == [3, 3, 4, 4]

The sort method in the java.util.Collection class is part of the Groovy JDK, meaning it’s one of the methods Groovy adds to the standard Java libraries. It takes a closure of either one or two arguments. In this case, I’m using the one-argument closure, which is used to select a property on which to base the sort. By specifying it.days in the closure, I’m telling the sort method to sort the courses based on their days property. Then I verify that the sort worked by checking that the courses are the right order, using the spread-dot operator to just look at the number of days.

In class the question that always comes up is, can I sort by days and then by name? In other words, if two courses have the same number of days, can I then sort by the name property?

That’s what the two-argument closure on the sort method is for. The two arguments are references to any pair of courses, and the closure should return a negative number, zero, or positive number according to whether the first course is less than, equal to, or greater than the second.

Here’s where things get amusing. The sort I want is:

courses.sort { a,b ->
    a.days <=> b.days ?: a.name <=> b.name
}

assert courses.toString() == '[(Grails,3), (Hibernate,3), (Groovy,4), (Spring,4)]'

The body of the closure on sort uses the spaceship operator <=>, which returns -1, 0, or 1 depending on whether the left side is less than, equal to, or greater than the right side. I use spaceship to compare the days properties. Then I add the Elvis operator ?: which means if the days comparison is not zero, use it, but otherwise use the following comparison, which uses another spaceship to compare by name.

It’s only after writing the code in class that one of the students pointed out that I had Elvis in between two spaceships, leading to the following observations:

  1. The spaceships are there to return Elvis to his home planet
  2. It takes two spaceships, working in tandem, to carry Elvis away, in much the same way two swallows can carry a coconut in tandem
  3. Therefore, the Elvis being carried away must be the fat Elvis from the 70s, rather than the thin, cool Elvis from the 50s

Either way, after the sort is finished, Elvis has left the building.

Thank you, thank you very much.

Groovy StubFor magic

I finished revising the testing chapter in Making Java Groovy (the MEAP should be updated this week), but before I leave it entirely, I want to mention a Groovy capability that is both cool and easy to use. Cool isn’t the right word, actually. I have to say that even after years of working with Groovy, what I’m about to describe still feels like magic.

Here’s the issue: I have a class that uses one of Google’s web services, and I want to test my class even when I’m not online. That means I need to mock the dependency, which isn’t all that hard. The problem is that there’s no explicit way to get my mock object into my own service. Yet, with Groovy’s MockFor and StubFor classes, I can mock a dependency, even when it’s instantiated as a local variable inside my class.

Let me show you the code. I’ll start with a simple POGO called Stadium:

class Stadium {
    String street
    String city
    String state
    double latitude
    double longitude
    
    String toString() {
        "($street,$city,$state,$latitude,$longitude)"
    }
}

I use this in my Groovy Baseball application, which accesses MLB box scores online and displays the daily results on a Google Map. The Stadium class holds location data for an individual baseball stadium. When I use it, I set the street, city, and state and have the service compute latitude and longitude for me.

My Geocoder class is based on Google’s restful geocoding service.

class Geocoder {
    String base = 'http://maps.google.com/maps/api/geocode/xml?'
   
    void fillInLatLng(Stadium stadium) {
        String urlEncodedAddress =
                [stadium.street, stadium.city, stadium.state].collect {
                    URLEncoder.encode(it,'UTF-8')
                }.join(',+')
        String url = base + [sensor:false, address:urlEncodedAddress].collect { it }.join('&')
        def response = new XmlSlurper().parse(url)
        String latitude = response.result.geometry.location.lat[0] ?: "0.0"
        String longitude = response.result.geometry.location.lng[0] ?: "0.0"
        stadium.latitude = latitude.toDouble()
        stadium.longitude = longitude.toDouble()
    }
}

First I take the stadium’s street, city, and state and add them to a list. Then the collect method is used to apply a closure to each element of the list, returning the transformed list. The closure runs each value through Java’s URLEncoder. In looking at the Google geocoder example, I see that they separate the encoded street from the city and the city from the state using “,+“, so I do the same using the join method.

The Google geocoding service requires a parameter called sensor, which is true if the request is coming from a GPS-enabled device and false otherwise. In the Groovy map, I set its value to false, and set the value of the address parameter to the string from the previous line. The collect method on the map converts each entry to “key=value“, so joining with an ampersand and appending to the base value gives me the complete URL for the stadium.

Most restful web services try to provide their data in a format requested by the user. The content negotiation is usually done through an “Accept” header in the HTTP request, but in this case Google does something different. They support only XML and JSON output data, and let the user select which one they want through separate URLs. The base URL in the service above ends in xml. Google lists the JSON version as preferred, but that’s no doubt because they expect the requests to come through their own JavaScript API. I’m making the request using Groovy, and the XmlSlurper class makes parsing the result trivial.

(Since Groovy 1.8, the JsonSlurper class also makes parsing JSON trivial, and I have a version that does that, too, but the difference really isn’t significant here.)

The resulting block of XML that is returned by the service is fairly elaborate, but as you can see from my code, the data is nested through the elements GeocodeResponse/result/geometry/location/lat and GeocodeResponse/result/geometry/location/lng. After invoking the parse method (which returns the root element, GeocodeResponse), I just walk the tree to get the values I want.

I do have to protect myself somewhat. The Google service isn’t nearly as deterministic as I would have expected. Sometimes I get multiple locations when I search, so I added the zero index to make sure I always get the first one. Also, some time during the last year Google decided to start throttling their service. I have a script that uses the Geocoder for all 30 MLB stadiums, and unfortunately it runs too fast (!) for the Google limits. I know this because I start getting back null results if I don’t artificially introduce a delay. That’s why I put in the Elvis operator with the value 0.0 if I don’t get a good answer.

So much for the service; now I need a test. If I know I’m going to be online, I can write a simple integration test as follows:

import static org.junit.Assert.*;
import org.junit.Test;

class GeocoderIntegrationTest {
    Geocoder geocoder = new Geocoder()
    
    @Test
    public void testFillInLatLng() {
        Stadium google = new Stadium(street:'1600 Ampitheatre Parkway',
            city:'Mountain View',state:'CA')
        geocoder.fillInLatLng(google)
        assertEquals(37.422, google.latitude, 0.01)
        assertEquals(-122.083, google.longitude, 0.01)
    }
}

I’m using Google headquarters, because that’s the example in the documentation. I invoke my Geocoder’s fillInLatLng method and check the results within a hundredth of a degree.

(The fact that the Google geocoder returns answers to seven decimal places is evidence that their developers have a sense of humor.)

Now, finally, after all that introduction, I reach the subject of this post. What happens if I’m not online? More to the point, how do I test the business logic in the fillInLatLng method without requiring access to Google?

What I need is a mock object, or, more precisely, a stub.

(A stub stands in for the external dependency, called a collaborator. A mock does the same, but also validates that the caller accesses the collaborator’s methods the right number of times in the right order. A stub helps test the caller, and a mock tests the interaction of the caller with the collaborator, sometimes called the protocol. Insert obligatory link to Martin Fowler’s “Mocks Aren’t Stubs” post here.)

In my Geocoder class, the Google service is accessed through the parse method of the XmlSlurper. Even worse (from a testing point of view), the slurper is instantiated as a local variable inside my fillInLatLng method. There’s no way to isolate the dependency and set it from outside, either as an argument to the method, a setter in the class, a constructor argument, or whatever.

That’s where Groovy’s StubFor (or MockFor) class comes in. Let me show it in action. First, I’ll set up the answer I want.

String xml = '''
    <root><result><geometry>
        <location>
            <lat>37.422</lat>
            <lng>-122.083</lng>
        </location>
    </geometry></result></root>'''
    
def correctRoot = new XmlSlurper().parseText(xml)

The xml variable has the right answer in it, nested appropriately. I use the XmlSlurper to parse the text and return the root of the tree I want.

Now I need a Stadium to update. I deliberately put in the wrong street, city, and state to make sure that I only get the right latitude and longitude if I insert the stub correctly.

Stadium wrongStadium = new Stadium(
    street:'1313 Mockingbird Lane',
    city:'Mockingbird Heights',state:'CA')

(Yes, that’s a pretty obscure reference. For details, see here. And yes, I’m old. If you’re in the right age group, though, you now have the show’s theme song going through your head. Sorry.)

The next step is to create the stub and set the expectations.

def stub = new StubFor(XmlSlurper)
stub.demand.parse { correctRoot }

The StubFor constructor takes a class as an argument and builds a stub around it. Then I use the demand property to say that when the parse method is called, my previously computed root is returned rather than actually going over the web and parsing anything.

To put the stub into play, invoke its use method, which takes a closure:

stub.use {
    geocoder.fillInLatLng(wrongStadium)
}

That’s all there is to it. By the magic of Groovy metaprogramming, when I invoke the parse method of the XmlSlurpereven when it’s instantiated as a local variable — inside the use block the stub steps in and returns the expected value.

For completeness, here’s the complete test class:

import static org.junit.Assert.*
import groovy.mock.interceptor.StubFor
import org.junit.Test

class GeocoderUnitTest {
    Geocoder geocoder = new Geocoder()
    
    @Test
    public void testFillInLatLng() {
        Stadium wrongStadium = new Stadium(
            street:'1313 Mockingbird Lane',
            city:'Mockingbird Heights',state:'CA')
        
        String xml = '''
        <root><result><geometry>
            <location>
                <lat>37.422</lat>
                <lng>-122.083</lng>
            </location>
        </geometry></result></root>'''
        
        def correctRoot = new XmlSlurper().parseText(xml)
        
        def stub = new StubFor(XmlSlurper)
        stub.demand.parse { correctRoot }
        
        stub.use {
            geocoder.fillInLatLng(wrongStadium)
        }
        assertEquals(37.422, wrongStadium.latitude, 0.01)
        assertEquals(-122.083, wrongStadium.longitude, 0.01)
    }
}

Since I’m only calling one method and only calling that method once, a stub is perfectly fine in this case. I could invoke the verify method if I wanted to (MockFor invokes verify automatically but StubFor doesn’t), but it doesn’t really add anything here.

There is one limitation to this technique, which only comes up when you’re doing the sort of Groovy/Java integration that is the subject of my book. You can only use StubFor or MockFor on a class written in Groovy.

All this code is available in the book’s Github repository at http://github.com/kousen/Making-Java-Groovy. This particular example is part of Chapter 5: Testing Java and Groovy.

As a final note, I should say that I dug into all of this, worked out all the details, and tried it in several examples. Then I finally did what I should have done all along, which was look it up in Groovy In Action. Of course, there it was laid out in detail over about five pages. Someday that will stop happening to me. :)

GroovyShellTestCase for testing Groovy scripts

I try to keep up with developments in the Groovy and Grails worlds. I really do. I follow most of the core team members on Twitter. I listen to the Grails Podcast when I can. I go to many conferences and attend other talks when I’m not speaking. I try to follow the email lists, though they’re way too high volume. I even have a Google+ account, though I don’t check it very often.

It’s all too much, actually. As I get older, I find that keeping up isn’t just a question of time, it’s a question of energy. Sometimes I’ll manage to catch up on my Twitter feed and am too tired to do much else.

So new developments slip by me. I guess that’s good, since it’s indicative of an active ecosystem, but it can be frustrating at times.

The one that forms the subject of this blog post is pretty trivial and arguably not worth writing about, but I missed it when it first came out so I thought I’d document it here.

Say you have a script in Groovy and you want to test it. You can execute the script programmatically using GroovyShell, and supply any needed variables with an instance of the Binding class.

Here’s a trivial example. I have the following massively complex, powerful script:

z = x + y

Say this is saved in a file called ‘math.groovy‘. Since none of the variables x, y, and z are declared at all in the script (not even using def), they can be accessed through a Binding object.

Binding binding = new Binding()
binding.x = 3; binding.y = 4
GroovyShell shell = new GroovyShell(binding)
shell.execute(new File('math.groovy'))
assert 7 == binding.z

This is easy enough to convert into a test case, as a subclass of GroovyTestCase.

class ScriptTests extends GroovyTestCase {
    void testMath() {
        Binding binding = new Binding()
        binding.x = 3; binding.y = 4
        GroovyShell shell = new GroovyShell(binding)
        shell.evaluate(new File('math.groovy'))
        assertEquals 7, binding.z
    }
}

By extending GroovyTestCase, this entire script can be executed at the command line or inside the Groovy Console without adding any additional library dependencies of any kind (not even JUnit). When I ran it, the result was:

.
Time: 0.037

OK (1 test)

That’s all well and good. I was writing up examples like this for my book (Making Java Groovy, available through the Manning Early Access Program at http://manning.com/kousen) and decided to look at the Groovy API for GroovyTestCase. Lo and behold, what do I stumble upon but a class called GroovyShellTestCase. The class was authored by Alex Tkachman (so you know it’s good :) ), presumably back in 2008 if the copyright statement is to be believed. Of course, the copyright could just be a copy-and-paste issue*.

*Which is what I like to call the CAP Design Pattern — how to take an error in one small part of your system and distribute it throughout the entire code base.

The GroovyDocs are a bit thin on that class, but they say (and I quote), “GroovyTestCase, which recreates internal GroovyShell in each setUp()”. The class has a protected field called shell of type GroovyShell, and a method called withBinding with a couple of overloads. For my purposes, I want the overload that takes two arguments, the first being a Map of binding variables, and the second being a closure to be executed. The method executes the closure with the given binding:

protected def withBinding(Map map, Closure closure)

Therefore, if I extend GroovyShellTestCase, I can rewrite my test as:

class ScriptTests extends GroovyShellTestCase {
    void testMath() {
        def result = withBinding( [x:3, y:4] ) {
            shell.evaluate(new File('math.groovy'))
            shell.context.z
        }
        assertEquals 7, result
    }
}

The map supplies x and y to the binding, which is automatically supplied to the instantiated shell. I can get the result by calling the getContext method on the shell (i.e., access the context property) which returns the binding, and then accessing its z property. I’m taking advantage of the fact that the implementation of the withBinding method includes “return closure.call()“, so the last evaluated expression in the closure is returned automatically.

This isn’t a huge deal, but it’s there and presumably it’s been there for a while and I never knew it. Now I know. Even better, now you know. Maybe you’ll have a use case that needs it. I’ve been trying to make sure that all my scripts in my book have test cases, and this gives me a convenient way to write them.

My only disappointment in discovering this is that when I looked for the tests for the GroovyShellTestCase class, I didn’t find any. In the Groovy distribution under src/test/groovy/util, there’s GroovyScriptEngineTest, GroovyTestCaseTest, and even GroovySwingTestCase, but no dedicated class for testing GroovyShellTestCase. Maybe that’s my opportunity to add one and make a (tiny, but useful) contribution to the language. That would be fund to do just to write a class called GroovyShellTestCaseTest. Heck, that’s only one small step away from the palindromic GroovyShellTestCaseTestShell.groovy. :)

Up and Running Groovy: An O’Reilly screencast for my Manning book (wait, what?)

Way back in the Spring of 2009, I was contacted by an editor at O’Reilly about doing a couple of “targeted video/screencasts”. This person (who is no longer there — I’d give you his name but I haven’t asked his permission yet) had the idea of getting people together in an informal setting and talking about state of the art technologies.

To make a long story short (it’ll get longer later), I wound up flying to Sebastopol, CA in late April, 2009, and we recorded two extended screencasts at the Westerbeke Ranch Conference and Event Center in the heart of Sonoma Valley wine country. We were the only people there, so it was pretty quiet. It also hadn’t yet warmed up, so we were on the chilly side, but that wasn’t a problem either. Oh, and the wine was good, too. :)

The format of the screencasts was a conversation between me and a single developer, shifting between us and the laptop I was using (a Sony VAIO, with a Camtasia install that almost brought it to its knees).

One of those screencasts, on Enterprise Java, has mercifully been lost to the mists of time. The other now has the title “Up and Running Groovy“, and much to my surprise was released to Safari online today. You can find it at http://my.safaribooksonline.com/video/-/9781449323387.

The code holds up surprisingly well, even after 2 1/2 years. The funniest part, though, is that the second slide mentions the upcoming O’Reilly book “Making Java Groovy“, co-authored by Scott Davis (!) and me.

Um, yeah. The book did start out with Scott, and in late 2009 he signed it over to me. In early 2010, O’Reilly cancelled it, along with many others, citing a lack of demand for Groovy. The people at Manning saw the world differently, and now you can get over half of it through the Manning Early Access Program at http://manning.com/kousen.

So here we are, years later, with the odd situation of an O’Reilly screencast that is effectively marketing a Manning book. I don’t think I could make this stuff up.

If you actually watch it and have any questions, please feel free to send them along. I assure you all questions or comments I’m getting these days are changing how I’m writing my book.

Making Swing Groovy, Part III: EDT

In this entry in my “Making Swing Groovy” series, I want to talk about threading issues. Specifically, how to work with the Event Dispatch Thread. As a step along the way, let me first respond to a comment made about my first post in this series.

Kirill Grouchnikov collects interesting Swing-related links every week. He was kind enough to link to my first post, and rightly pointed out that in my Java example, I’d make some errors. As he said,

“… the Swing example is not the best one, violating the EDT rules, working with the content pane and not centering the frame in the monitor, and the author admits some of these points.”

Let me say up front that I’m grateful for his comments. That’s how I learn. Part of the reason I post here (other than just the joy of sharing what I’ve learned) is to find out what I’ve been doing wrong, or, if I’m okay, what I can do better. One of the principles I live by is, “I’m often wrong, but I don’t stay wrong.” So keep those cards and letters coming. :)

Here’s the code that Kirill addressed:

import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class EchoGUI extends JFrame {
	private JTextField input = new JTextField(20);
	private JLabel prompt = new JLabel("Input text: ");
	private JLabel echo = new JLabel("Echo: ");
	private JLabel output = new JLabel();

	private Container cp = this.getContentPane();

	public EchoGUI() {
		super("Echo GUI");
		cp.setLayout(new GridLayout(0,2));  // 2 cols, as many rows as necessary

		cp.add(prompt);
		cp.add(input);
		cp.add(echo);
		cp.add(output);

		input.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				output.setText(input.getText());
			}
		});

		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		setSize(300,100);
		setVisible(true);
	}

	public static void main(String[] args) {
		new EchoGUI();
	}
}

First, Kirill was right about my working with the content pane rather than adding my components directly to the JFrame instance. I remember way back in the Java 1.0 days (holy AWT, Batman), you added components directly to the instance of java.awt.Frame. Then, when Swing came along, you weren’t supposed to do that any more. Instead, you added to the content pane in front of the JFrame. That held true for Java 1.2, 1.3, and 1.4. Finally, in Java 1.5, you could go directly to the JFrame again, because now adding to the frame redirects to adding to the content pane. I need to retrain myself to do that.

Here is a link to a good post that explains why everything changed and then changed back.

Another of Kirill’s comments was that I didn’t center the frame on the monitor. I used to do that via code like

Toolkit tk = Toolkit.getDefaultToolkit();
Dimension screenSize = tk.getScreenSize();

From that I can get the width and height of the screen, and then using the width and height of the frame I can center everything. I can do that, but here it seems a bit like overkill.

Finally, we come to the real issue, which is also the subject of this post. As he said, I violated the EDT rules, and that’s bad.

Arguably Rule #1 of Swing GUI’s is “Only update GUI Elements in the Event Dispatch Thread (EDT).” From what I gather from frequent posts about that issue across the web, this is an error as common to Swing developers as forgetting to close database connections is when writing JDBC code. And again, this is one of those situations in Swing where the rules have changed multiple times, although maybe it’s more accurate to say that the rule hasn’t changed, but the way to implement it has.

First, some quick background. Every Swing program involves multiple threads. First, there are the initializing threads, which start up the GUI. In a Java application, that’s the main method. Then there is the Event Dispatch Thread, which maintains an Event queue that handles all the GUI updates, and finally there are any background threads that are used to manage long-running processes. If you make sure that non-GUI processes are off the EDT, then the GUI will remain responsive while the application is doing other work.

As of JDK 1.6, the standard library now has the class javax.swing.SwingUtilities, which contains the methods invokeLater and invokeAndWait. According to the concurrency lesson in the Swing tutorial, the proper way to create a GUI is

public static void main(String[] args) {
    SwingUtilities.invokeLater(new Runnable() {
        @Override
        void run() {
            \\  ... instantiate the GUI ...
        }
    );
}

The invokeLater method creates the Runnable object and gives it to the EDT to add to the event queue. The alternative method invokeAndWait does the same thing, but it blocks until the task is completed.

What does Groovy bring to this picture? As usual, Groovy simplifies matters. Groovy adds three helpful methods to groovy.swing.SwingBuilder: edt, doLater, and doOutside.

What do they do? One of the best things about using an open source API is that, well, you have access to the source code. For the edt method, the implementation looks like (paraphrased):

public SwingBuilder edt(Closure c) {
    if (SwingUtilities.isEventDispatchThread()) {
        c.call(this)
    } else {
        // ...
       SwingUtilities.invokeAndWait(c)
       // ...
    }
}

In other words, if we’re in the EDT already, invoke the closure. If not, call invokeAndWait to get to the EDT.

Likewise, for doLater:

public SwingBuilder doLater(Closure c) {
    // ...
   SwingUtilities.invokeLater(c)
   // ...
}

and for doOutside:

public SwingBuilder doOutside(Closure c) {
    // ...
   Thread.start(c)
    // ...
}

So what’s the bottom line?

  • edt: use the EDT through invokeAndWait
  • doLater: use the EDT through invokeLater
  • doOutside: create a worker thread and start it (off the EDT)

Incidentally, SwingBuilder also has a build method specifically designed to construct the GUI. How does it handle threading?

public static SwingBuilder build(Closure c) {
    SwingBuilder builder = new SwingBuilder()
    return builder.edt(c)
}

That’s the whole method — create the buillder and then build the GUI on the EDT, synchronously. That’s why all of our previous examples of SwingBuilder, which only used the build method on the builder, ran correctly. They’re doing the initial construction on the EDT, as they should.

Ultimately, practical examples of Groovy Swing code uses actions that take advantage of these methods, as in

swing.actions() {
    action(name:'myMethod') {

        doOutside {
            model.prop = textField.text
            // ... other model property updates ...
            def ok = someLongRunningService(model)

            doLater {
                model.ok = ok
}  }   }  }

And there you have it. Grab the data and update the model outside the EDT, then run the long running application. When it’s finished, update the GUI in the EDT. (Note that here we’re updating the model in the EDT because the model properties are bound to the GUI elements, so changes in model properties will result in a GUI update. See my previous post in this series for details.)

From here it’s only a short step to Griffon.

Making Swing Groovy, Part II: Binding

In my previous post in this series, I presented a trivial Echo GUI written in Groovy.  By using SwingBuilder and closures, the code for the GUI was dramatically simplified compared to the Java version.  But Groovy can go beyond that.  In this post, I’ll talk about the bind method and the @Bindable annotation, which help transform Swing development into the MVC structure of Griffon.

The code for the Echo GUI currently consists of:

import groovy.swing.SwingBuilder
import javax.swing.WindowConstants as WC

SwingBuilder.build() {
    frame(title:'Echo GUI', size:[300,100],
        visible:true, defaultCloseOperation:WC.EXIT_ON_CLOSE) {
        gridLayout(cols: 2, rows: 0)
        label 'Input text: '
        input = textField(columns:10, 
            actionPerformed: { output.text = input.text })
        label 'Echo: '
        output = label()
    }
}

The closure assigned to the actionPerformed property transfers the input from the text field to the output label.  In order to make that happen, both the field and the label were given names that could be referenced inside the closure.

Groovy 1.5+ includes a method called bind, which works with bound properties in the ancient JavaBeans specification.  For those whose only exposure to JavaBeans is through POJO’s on the server side, the original JavaBeans framework was designed to support GUI builders.  It looked and felt much like building GUIs in VB, in that you dragged these “beans” onto a palette, hooked them together, and set the values of their properties.  It was a way of writing Java user interfaces without writing any Java code, at least until you wanted the various widgets to actually do something.

I remember back around 1998, I convinced my boss at the time to purchase Sun’s proposed IDE based on beans.  I think it was called Sun Java WorkBench, or something like that.  It cost about $99, and it came with beans that you could drag and drop, and you could add your own jar files full of beans as well.  While it looked pretty cool, you didn’t have the source code for any of the beans, which limited their usefulness.

Java on the client side didn’t really take off, and the market for the IDE certainly didn’t pan out.  I do remember that the JavaBeans specification — written largely to support the client-side development model — brought us many aspects of Java that we take for granted now.  My first encounter with serialization came from there, as well as reflection, though they used the extremely awkward name introspection for it.  In addition to implementing java.io.Serializable, JavaBeans according to the spec were also supposed to have default constructors and the now-infamous naming convention for getters and setters for all the properties.  Actually, providing a getter method was sufficient to define a property of a JavaBean.

The spec also referred to various types of properties, like bound and constrained, and JavaBeans were also supposed to implement the PropertyChangeListener interface.

Very few Java programs were actually written using those JavaBeans, and the expected third-party market in JavaBeans libraries never seemed to develop.  I seem to recall that there were a couple of success stories (wasn’t IBM’s VisualAge for Java supposed to be written using the original JavaBeans spec?), but mostly the whole technology went away.

It wasn’t until a few years later that JavaBeans re-emerged, as the way to get Java code out of JavaServer Pages.  Sun’s Model 1 architecture consisted entirely of JSPs and JavaBeans, with no explicit servlets anywhere.  Model 2 changed all that by using servlets for controllers, but that came later.  By then, though, people used what we now call POJO’s for model classes, and you were still supposed to make your beans serializable, but all that stuff about property change listeners was largely ignored.

Groovy gives us a chance to use JavaBeans as model classes in an especially easy way.  First, here’s an illustration of a simple GUI that uses the bind method in Groovy.

import groovy.swing.SwingBuilder
import javax.swing.WindowConstants as WC
import java.awt.BorderLayout as BL

SwingBuilder.build() {
    frame(title:'Binding to Slider', pack:true, visible:true, 
        defaultCloseOperation:WC.EXIT_ON_CLOSE) {
        panel(constraints:BL.CENTER) {
          slider(id:'sl')
        }
        panel(constraints:BL.SOUTH) {
          label 'Slider value: '
          label(text:bind(source:sl, sourceProperty:'value'))
        }
    }
}

Here we’re taking advantage of the fact that all Swing widgets extend Component, which means they support property change listeners.  In this case, we have a slider with a property called value.  The bind method assigns the text of the label to the value property of the slider.  Dragging the slider immediately updates the label.

This is seriously cool, and means that the Echo GUI shown above can be made even more responsive by replacing the actionListener by binding the output label directly to the input text field.

import groovy.swing.SwingBuilder
import javax.swing.WindowConstants as WC

SwingBuilder.build {
    frame(title: 'Regular Binding (Groovy)', size: [300,100], 
        visible:true, defaultCloseOperation: WC.EXIT_ON_CLOSE ) {
        gridLayout(cols: 2, rows: 0)
        label 'Input text: '
        textField(columns:10, id:'tf')
        label 'Echo: '
        label(text:bind(source:tf, sourceProperty:'text'))
    } 
}

The result is that now, any characters typed into the text field are immediately transferred into the label. Deletes work the same way. The text in the output label is bound to the value of the input text field.

While this is interesting and even useful, a true model-view-controller architecture wouldn’t always bind widgets to other widgets. Instead, input values would be transfered to a model class, and then the model values would be sent to the output view. What we need, therefore, is a way to bind the view elements to an actual Java bean.

If this was Java, we would introduce a class that supported property change capabilities. Consider such a model class in Java:

import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;

public class Message {
    private String text;
    private PropertyChangeSupport pcs = new PropertyChangeSupport(this);

    public String getText() { 
        return text; 
    }

    public void setText(String text) { 
        pcs.firePropertyChange("text", this.text, this.text = text); 
    }

    public void addPropertyChangeListener(PropertyChangeListener listener) {
        pcs.addPropertyChangeListener(listener);
    }
	
    public void removePropertyChangeListener(PropertyChangeListener listener) {
        pcs.removePropertyChangeListener(listener);
    }
}

The Message class has a single property, called text. It also relies on the PropertyChangeSupport class to enable it to add and remove property change listeners. When the text property is changed, the setText method fires a property change event to all the listeners, where the arguments to the firePropertyChange method are the name of the property, its old value, and the new value.

How does Groovy simplify this? The key is the @Bindable annotation, which is currently only in Groovy 1.6 beta 2. Fortunately, that version is included in Griffon, though I did go to the trouble to download and rebuild it myself (a post for another time).

Using Groovy 1.6b2, here’s the equivalent Groovy bean:

import groovy.beans.Bindable

class Message {
    @Bindable def text
}

Seems almost unfair, doesn’t it? Add an annotation to the field, and you’re done. It’s hard to get much simpler than that.

Now all you need is a listener. In Java land, the GUI would use something like:

//...
    private Message msg = new Message();
//...
    msg.addPropertyChangeListener(new PropertyChangeListener(){
        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            output.setText((String) evt.getNewValue());
        }
    });
//...

again using an anonymous inner class to respond to the change. By contrast, here is the Groovy version (where in this case the code is sufficiently succinct that I can include the whole thing):

import groovy.swing.SwingBuilder
import javax.swing.WindowConstants as WC

def model = new Message()

SwingBuilder.build() {
    frame(title:'Echo GUI', size:[300,100],  
        visible: true, defaultCloseOperation:WC.EXIT_ON_CLOSE) {
        gridLayout(cols: 2, rows: 0)
        label 'Input text: '
        input = textField(columns:10, 
            actionPerformed: { model.text = input.text })
        label 'Echo: '
        label(text: bind { model.text })
    }
}

Once again, this won’t work unless you’re using Groovy 1.6b2 or above. The bind method has been modified to take a closure as its last argument, and the closure in question refers to the text property of the model, rather than to another widget. Note that now I’ve gone back to implementing actionListener, because I have to get the text value from the view into the model, so it’s not quite as clean as before. That could be changed, but at the moment it seems reasonable to do it that way.

Of course, if we have a model and we have a view, what we need next is a controller. Griffon shows how to do that, but I’ll leave it for another post.

The bottom line is that by using Groovy’s bind method and @Bindable annotation, constructing a GUI based on a realistic MVC architecture is now viable, and even easy.

Making Swing Groovy, Part I

I’ve been spending a lot of time lately trying to understand how much Groovy improves Swing user interfaces. Like so many Java developers, I rarely write client-side programs. Almost all of my time and effort with Java over at least the last five years has been on the server side, mostly with frameworks like Struts, and then open source projects like Spring and Hibernate. During all that time, the client-side interface was restricted to what HTML and CSS can handle.

Of course, the growth of Ajax changed a lot of that. I like several of the major Ajax libraries, like prototype, scriptaculous, jQuery, YUI, and so on. One of the interesting trends I’ve been watching in the industry is whether browser-based GUIs in the future will be written in a Java component library that renders in HTML (like JSF), or written in Java libraries that translate to Ajax/JavaScript (like GWT), or are written using JavaScript components directly (like in YUI or dojo).

Still, I used to write user interfaces in Swing. Several years ago I wrote a Jeopardy-like game that I still use in training classes, where the game board itself is a Swing UI and the clients all have “buzzers” that connect to the game board via RMI. One of my most interesting, and certainly most fragile, projects was about ten years ago when I had to put a Swing GUI on top of a Fortran program (shudder). In case you’re wondering, you can’t get there from here. You have to go Java to C via JNI, and then C to Fortran (even though they handle arrays differently). It’s basically like putting an notch in a beam and telling it to break right here.

But those are stories for another day. Suffice it to say that I feel quite comfortable writing Swing GUIs in raw code (as opposed to graphical drag-and-drop interfaces), complete with inner classes to implement ActionListeners or the like for each button, and so on. I still struggle a bit with the intricacies of GridBagLayout, but I can get pretty far with lots of JPanels and combinations of BorderLayout and FlowLayout.

So when it came time to see what Groovy brought to the table, I thought I was quite prepared. Imagine my surprise to find that, believe it or not, in the last several years the field actually moved on, despite the fact that I almost never get requests for training classes in Swing or related technologies. A lot of people (Andres Almiray, Danno Ferrin, Geertjan, and many more) have spent considerable time and effort applying Groovy to user interfaces and making all kinds of progress.

The culmination of all of this effort is the new, seriously cool, Griffon framework. Griffon promises to bring Grails-like productivity improvements to client-side Java applications. The more I learn about it, the more impressed I am. It’s been a bit disheartening, however, to find out how much I still have to learn before I really understand it.

No matter. I like to say that I’m often wrong, but I rarely stay wrong. My next few posts here will be dedicated to principles that I’ve been learning about user interfaces in Groovy. Hopefully, in addition to providing a nice record for me of what I’m learning, maybe this will help someone else avoid my mistakes.

In this first post, let’s get the really well-known stuff out of the way. That’s the wonderful elegance of Groovy’s groovy.swing.SwingBuilder. SwingBuilder is a great Groovy class, well-described in GinA, that let’s you create Swing interfaces almost declaratively.

Here’s a trivial Swing application in Java. All it does is take text typed in a text field and echoes it in the text of a label. It’s about a simple as Swing applications come.

import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;
import javax.swing.WindowConstants;

public class EchoGUI extends JFrame {
	private JTextField input = new JTextField(20);
	private JLabel prompt = new JLabel("Input text: ");
	private JLabel echo = new JLabel("Echo: ");
	private JLabel output = new JLabel();
	
	private Container cp = this.getContentPane();
	
	public EchoGUI() {
		super("Echo GUI");
		cp.setLayout(new GridLayout(0,2));  // 2 cols, as many rows as necessary
		
		cp.add(prompt);
		cp.add(input);
		cp.add(echo);
		cp.add(output);
		
		input.addActionListener(new ActionListener() {
			@Override
			public void actionPerformed(ActionEvent e) {
				output.setText(input.getText());
			}
		});
		
		this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		setSize(300,100);
		setVisible(true);
	}
	
	public static void main(String[] args) {
		new EchoGUI();
	}
}

First of all, this shows me to be an “old school” Swing developer, because I made my application extend JFrame rather than contain a JFrame instance. The trend these days is always to favor composition over inheritance, partly to reduce the coupling and partly to make testing easier (I’ll have more to say about testing Swing UIs in a future post). Still, this is the way I learned to do it, and I still fall into old habits, especially for trivial examples.

Second, I’m also arguably violating best practices because my main method instantiates the GUI directly, rather than calling SwingWorker.invokeLater to make sure all user interface updates are done in the Event Dispatch Thread (EDT). You can generally get away with this here, though, because until the GUI is actually rendered it isn’t much of a problem. Understanding the details of running on the EDT or not, however, is a big issue for later, too.

Also, I’m still in the habit of adding components to the content pane. I remember vividly when I had to rewrite all my existing Swing apps to add to content pane instead of directly to the frame itself, and I still do that, even though I don’t think it’s strictly necessary any more.

Finally, I did something here I generally don’t do, which is to use an anonymous inner class to handle the action listener for the button. Normally I create an actual (named) inner class for each component that generates events, and add an instance of each to the relevant component. Here, for example, I would normally write an inner class called something like EchoListener, and then add an instance of it to the button. Still, with only one button and an almost trivial inner class, it seemed easier to add it directly, even though arguably this is the ugliest syntax in all of Java, with the possible exception of generics.

Groovy’s SwingBuilder cuts this example down to practically nothing.

import groovy.swing.SwingBuilder
import javax.swing.WindowConstants as WC

SwingBuilder.build() {
	frame(title:'Echo GUI', size:[300,100],  
		visible:true, defaultCloseOperation:WC.EXIT_ON_CLOSE) {
		gridLayout(rows: 0, cols: 2)
		label 'Input text: '
		input = textField(columns:10, 
			actionPerformed: { output.text = input.text })
		label 'Echo: '
		output = label()
	}
}

The SwingBuilder means that I can just write words like frame, label, and textField, and, through the magic of metaprogramming, they are interpreted by the builder as Swing components. The other great part is that Groovy doesn’t force you to create an inner class just to hold a method. Closures are perfectly valid objects in their own right, so I can just assign one to the actionPerformed property of the text field, and I’m all set.

That’s an amazing savings, and it’s just the beginning. The combination of builder methods and closures cuts the amount of code required in a typical Swing GUI by a huge amount.

(I don’t know exactly how much, but I’m going to say 80%, because, as you may have heard, 80% of all statistics are made up on the spot.)

For more details, see GinA (Groovy in Action for the uninitiated, and if you are uninitiated and find Groovy cool, get thee hence to a bookstore and buy thee a copy) and the wiki pages at groovy.codehaus.org.

Still, this much I knew when I started my recent adventure. I had no idea about Groovy’s cool bind method, which dramatically simplifies the use of PropertyChangeListeners and is a great step along the way to a pure MVC architecture. Then there’s the @Bindable annotation that’s part of Groovy 1.6 beta 2, which makes it even easier. Then there’s the elegant way that Griffon lets you handle scheduling tasks inside or outside the EDT. I also realized that Swing hasn’t been idle, too, with the creation of the whole SwingX project and its associated set of components.

It’s been a wild ride for me recently, and I don’t feel I’m anywhere near finished. My feeling, though, is that Griffon is eventually going to be a very big deal. I know it’s making a big difference in how I think about Swing, and I’m looking forward to playing with it more and more.

Getting a list of Grails plugins programmatically

In September, I’m very happy to be giving a couple of presentations at the No Fluff, Just Stuff conference in the Boston area.  One of my presentations is a review of the various available Grails plugins.  To prepare for that, I thought I’d create a Grails application that acted as a survey, so people could rate the plugins they like.

One task is to get a list of available Grails plugins.  I wanted to do that programmatically, too, because I’d like to update the list automatically using the Quartz plugin (of course).

How do you get a list of available plugins?  My first thought was to do the HTML equivalent of screen scraping at the main plugin site, http://grails.org/Plugins .  At that site everything is nicely divided into categories, along with links to descriptions and more.

Screen scraping HTML is not fun, though.  I’ve done it before, when necessary, but it’s not very robust and tends to run into problems.  Many of those problems have to do with the fact that HTML is a mess.  Most web sites are filled with HTML that isn’t even well-formed, making processing it programmatically a real pain.

GinA, however, mentioned HTTPUnit as an easy way to access a web page.  Since it’s a regular old Java library, that meant I could use it with Groovy.  Therefore, my first attempt was:


import com.meterware.httpunit.WebConversation

def baseUrl = 'http://grails.org/Plugins'

def wc = new WebConversation()
def resp = wc.getResponse(baseUrl)

Unfortunately, I’m already in trouble even at that point.  If I run that, I get a massive exception stack trace with shows that the included Neko DOM parser choked on the embedded prototype JavaScript library.

While I was debating what to do about that (I really didn’t want to just open the URL, get the text, and start having Fun With Regular Expressions), I noticed a blog posting here, from someone named Isak Rickyanto, from Jakarta, Indonesia.

(A Java developer from Java.  How cool is that?  Or should I say, “how Groovy?” :) )

Isak points out that there is a list of Grails plugins at http://svn.codehaus.org/grails-plugins/ .  As a Subversion repository listing, it’s not full of JavaScript.  Even better, every plugin is listed as a simple link in an unordered list.

I therefore modified my script to look like this:


def baseUrl = 'http://svn.codehaus.org/grails-plugins/'

def wc = new WebConversation()
def resp = wc.getResponse(baseUrl)
def pluginNames = []
resp.links.each { link ->
    if (link.text =~ /^grails/) {
        def name = link.text - 'grails-' - '/'
        pluginNames << name
    }
}
println pluginNames

Here I’m taking advantage of the fact that the WebResponse class (returned from getResponse(url)) has a method called getLinks().  Since there was one link that had the name “.plugin-meta“, I decided to use a trivial regular expression to filter down to the links definitely associated with plugins.  The WebLink.getText() method then returned the text of the link, with gave values of the form

grails-XXX/

for each plugin.  One of the things I love about Groovy is that I can then just subtract out the characters I don’t want, which is how I added the actual plugin names to an array.

Unfortunately, while that’s part of what I want, that isn’t everything I want.  I’d like the version numbers and the descriptions, too, if possible.  I could go digging into the various directories and look for patterns, but a different idea occurred to me.

I finally remembered that the way I normally find out what plugins are available is to run the

grails list-plugins

command and look at the output.  You’ve probably seen it.  It gives an output like

Welcome to Grails 1.0.3 - http://grails.org/
Licensed under Apache Standard License 2.0
Grails home is set to: c:\grails-1.0.3

Base Directory: c:\
Note: No plugin scripts found
Running script c:\grails-1.0.3\scripts\ListPlugins.groovy
Environment set to development

Plug-ins available in the Grails repository are listed below:
-------------------------------------------------------------

acegi               <0.3>            --  Grails Spring Security 2.0 Plugin
aop                 <no releases>    --  No description available
audit-logging       <0.4>            --  adds hibernate audit logging and onChange event handlers ...
authentication      <1.0>            --  Simple, extensible authentication services with signup ....
autorest            <no releases>    --  No description available

etc.  So if I could get this output, I could break each line into the pieces I want with simple String processing.

How can I do that?  In the spirit of reducing it to a problem already solved, I realized I just wanted to execute that command programmatically and capture the output.  One way to do that is to take advantage of Groovy’s ability to run command line scripts (GinA covers this, of course, but so does Scott Davis’s most excellent Groovy Recipes book).  Here’s the result:


def names = []
def out = "cmd /c grails list-plugins".execute().text
out.split("\n").each { line ->
    if (line =~ /<.*>/) {
        def spaceSplit = line.split()
        def tokenSplit = line.split('--')
        def name = spaceSplit[0]
        def version = spaceSplit[1] - '<' - '>'
        def description = tokenSplit[-1].trim()
        names << name
    }
}

Basically I’m executing the list-plugins command at a command prompt under Windows (sorry, but that’s still my life), splitting the output at the carriage returns (for some odd reason, using eachLine directly kept giving me errors), and processing each line individually.  The lines listing plugins are the ones with version numbers in angle brackets (like <0.3>), and the descriptions came after two dashes.  It seemed easiest to just split the lines both ways in order to get the data I wanted.

I ran this script and the other script together to see if I got the same output.  Here’s the result:


println "From 'grails list-plugins': " + names
println "From svn repo: " + pluginNames
println "Difference: " + (pluginNames - names)

From 'grails list-plugins': ["acegi", "aop", "audit-logging", ..., "yui"]
From svn repo: ["acegi", "aop", "audit-logging", ..., "yui"]
Difference: ["extended-data-binding"]

Why the difference? From the list-plugins output, here’s the line for “extended-data-binding“:


ext-ui              <no releases>    --  No description available
extended-data-binding<0.2>            --  This plugin extends Grails' data binding ...

Yup, the name ran into the version number format.  Sigh. Of course, the other problem with this is that at the moment it’s dependent on my own system configuration (Windows, with the grails command in the path), which can’t be a good thing.

Finally, after all this work, I suddenly realized that I already have the script used to list the plugins.  As with all the other Grails commands, it’s a Gant script in the <GRAILS_HOME>\scripts directory called, obviously enough, ListPlugins.groovy.  According to the documentation at the top, it was written by Sergey Nebolsin for version 0.5.5.

What Sergey does is to go to a slightly different URL and then parse the results as XML.  His script accesses

DEFAULT_PLUGIN_DIST = "http://plugins.grails.org"

instead of the SVN repo location listed above, but if you go there, they look remarkably alike.  I wouldn’t be surprised if http://plugins.grails.org is simply an alias for the SVN repository.

Note that the script also creates a cached version of the plugin list, called plugins-list.xml, which is kept in the

"${userHome}/.grails/${grailsVersion}/plugins/"

directory.  That’s completely understandable, but a lousy location on a Windows box.  I never go to my so-called “user home” directory, so I would never occur to me to look there for information.

His script checks to see if that file is missing or out of date.  If it’s necessary to update it, he opens a URL and starts processing:


def remoteRevision = 0
new URL(DEFAULT_PLUGIN_DIST).withReader { Reader reader ->
    def line = reader.readLine()

...

    // for each plugin directory under Grails Plugins SVN in form of 'grails-*'
    while(line=reader.readLine()) {
        line.eachMatch(/<li><a href="grails-(.+?)">/) {
            // extract plugin name
           def pluginName = it[1][0..-2]

           // collect information about plugin
           buildPluginInfo(pluginsList, pluginName)
        }

etc.

So, in effect, he’s screen scraping the SVN page; he’s just doing a better job of it than I was.

Incidentally, the line in his script that lead to my parsing problems is on line 86:

plugins << "${pluginLine.padRight(20, " ")}${versionLine.padRight(16, " ")} --  ${title}"

I could bump up the padding by one, or learn to parse the output better. :) I expect the “right” answer, though, is to do what Sergey did, pretty much. Still, if all I have to do is add a little padding, it’s awfully tempting to just “reuse” Sergey’s existing script.

In an upcoming post, I’ll talk about how I used the RichUI plugin to apply a “star rating” to each entry so that people could vote. I don’t have the site ready yet, though. I’ll be sure to mention it when I do.

assert != assertEquals (duh)

It’s probably not great for my reputation to show how I made a very silly error, but since I did it so consistently I thought showing it might help somebody avoid it.

My Groovy course materials consist of far more scripts than classes. That’s probably not surprising, given that teaching Groovy involves writing lots and lots of quick-and-dirty examples. The problem with scripts, though, is that they’re not as easy to test as classes. With classes, I can create a class that extends GroovyTestCase, put in my tests and go. With scripts, though, the same process would require either executing the script from a Groovy class and checking the binding properties, or simply using assert statements.

In general, I chose the latter. In my scripts, I tried to complete each with at least one assert call that I could use later to validate the script.

Sounds like a reasonable approach, right? Sure, until you start going too quickly. What’s wrong with the following code?


// inject demo
def strings = ["Hello","World"]
int totalLength = strings.inject(0) { len, s ->
    len += s.size()
}
assert 10, totalLength

The code is intended to be a trivial illustration of the inject method for lists. The result is supposed to be the sum total of the lengths of all the strings in the list. Ignoring that there are many other ways to solve that problem, the difficulty here isn’t the inefficiency of the algorithm. No, it’s a trap that as a long-time Java developer I found very easy to fall into.

The problem is with my assert statement. The intention is to assert that the total length of the strings in the list is 10. Sure enough, executing this code has no errors. That’s not a big surprise (for me), because at first I started with a println statement to see what the value should be, and then I replaced println with an assertion.

Unfortunately, though, my assertion didn’t prove anything about the script. That becomes obvious if I add another line to the program:

assert 50000, totalLength

which passes just as easily.

What’s wrong? I’m using assert as though it was a two-parameter method, like assertEquals in GroovyTestCase.

What I’m trying to do is to specify the right answer followed by the actual test. What I’m actually doing is asserting that the first argument (a literal number) is true, and supplying an error message to print if not. By the Groovy truth, any non-zero number is always true, so my totalLength never needs to be converted to a string and printed as the the error message.

What I really want to use, of course, is

assert 10 == total, "total should be 10"

I think this is an easy trap for Java developers to fall into, because they’re not accustomed to the Groovy truth. In Java, only a real boolean expression can be true or false, not just a number.

What’s truly embarrassing is how many of my scripts were just asserting that a non-zero value was true, which always works.

Once I realized my mistake (because somebody pointed out one of my bad examples), I had to go back and fix all of my tests. They’re better now. :)

Using Groovy to determine Unicode characters

(Technically speaking, this post doesn’t require Groovy. You could do the same thing in Java. Still, as usual, Groovy is easier.)

I’m teaching a Groovy course this week and having a great time doing it. One of the exercises I put together is to create a concordance, which is a map relating individual words to the lines in a file on which they appear. The program is a variation on a similar one shown in Barclay and Savage’s Groovy Programming book, and is a good illustration of how easy it is to work with maps in Groovy.

A concordance needs to be based on some text somewhere, so I decided to use section 8.00 of the Official Rules of Baseball, which deals with the pitcher.

(And even after reading it again, I couldn’t really explain what a balk really is and what it isn’t, but so be it.)

I copied the text from the web page and pasted it into a text file. Then the exercise code reads the file line by line, breaks each line into words, and then adds them as keys to a map where the values are lists of line numbers. It’s a good example of using eachWithIndex, and map.get(word,[]) + 1, and so on. Once we’ve made each line lower case (so that ‘Pitcher’ and ‘pitcher’ are the same) and coerced the list values to Sets in order to eliminate duplicates, we’re pretty close to a reasonable solution.

The passage is filled with punctuation, however. Fortunately, the tokenize() method in String is overloaded to take a String argument representing the delimiters. Most of the delimiters are obvious and no problem at all (i.e., " .,;:()\'\").

It turns out, however, that the passage also includes sections like:

Pitchers are constantly attempting to “beat the rule” in their efforts to hold runners on bases and in cases where the pitcher fails to make a complete “stop” called for in the rules, the umpire should immediately call a “Balk.”

which are using so-called “smart” quotes. They don’t match the double-quotes in my delimiter string. In other places, there are also possessives which use “smart” apostrophes. How can I add those to my delimiters?

What I needed was the Unicode equivalents for the punctuation. If I know the Unicode values, I can add them as hex values to my delimiters string, like \uXXXX.

After some discussions, I decided to parse the entire passage character by character, and add all non-word characters to a map with their Unicode values. The code looks like this:


def delimiters = [:]
def data = new File('pitcherrules.txt').text
data.each { c ->
    def str = Integer.toHexString(c as int)
    if (!(c =~ /\w/)) {
        delimiters[c] = str
    }
}
println delimiters

It’s pretty straightforward once you know what to look for. Java supplies the Integer.toHexString() method, which takes an int. I read the entire passage into the data variable, then iterated over it, passing each character to the toHexString method. The key was to coerce the character to an int, otherwise I get a MissingMethodException.

I originally had a different expression in the if statement. I was using (c < 'A' || c > 'z') instead. The result included the numbers 0 to 9. By matching against a regular expression consisting of \w, though, I check for all word characters, which is equivalent to [A-Za-z0-9].

The output of the code is

[" ":"20", ":":"3a", ".":"2e", "\r":"d", "\n":"a", ",":"2c",
"(":"28", ")":"29", "’":"2019", "“":"201c", "”":"201d",
"-":"2d", "—":"2014", ";":"3b"]

which tells me that the Unicode values I need are \u2019, \u201c, \u201d, and \u2014.

It’s only a small part of a larger problem, but it’s an easy, useful, interesting script that was probably as much of a learning experience as the original lab. It’s all good. :)

Now the real question is how much of this will actually render properly in this blog post.

Follow

Get every new post delivered to your Inbox.

Join 517 other followers

%d bloggers like this: