English for Java


I had an interesting challenge today. I’m writing an object to XML converter that uses reflection to get bean property names for generated XML tags. It’s SAX based so I can throw it at the TrAX API without materializing any XML text and do a direct transform to whatever format. Enough back-patting and babbling about the complications of the code. The problem I faced was trying to break list properties into tags that reflected both plural and singular instances of the property name. In other words if I had an “Addresses” list property my code has to be savvy enough to create an “addresses” and a collection of “address” tags to hold the data. Likewise, if I have a “people” property it has to come up with a “people” tag that holds “person” tags.

I know the Grails project has code somewhere that deals with this very same problem but I’m impatient and rushed a solution to the table. I came up with a new method to add to my StringHelper utility object which seemed like an appropriate place for the algorithm. I developed the algorithm Test Driven style with the self imposed requirement of not requiring the access to a dictionary as it would needlessly complicate client code. Next thing you know I felt like I was in English class all over again. I’m now trying to figure out all the wierd twists of English nouns to develop an algorithm that would cause issues such as whether to strip the final “es” off of a word or just pull off the last “s”. Here’s my code:


    /**
     * Returns the non-plural form of a plural noun like: cars -> car, children -> child, people -> person, etc.
     * @param str
     * @return the non-plural form of a plural noun like: cars -> car, children -> child, people -> person, etc.
     */
    public String fromPlural(String str)
    {
        if(str.toLowerCase().endsWith("es") && ! shouldEndWithE(str)) return str.substring(0, str.toLowerCase().lastIndexOf("es"));
        else if(str.toLowerCase().endsWith("s")) return str.substring(0, str.toLowerCase().lastIndexOf('s'));
        else if(str.toLowerCase().endsWith("children")) return str.substring(0, str.toLowerCase().lastIndexOf("ren"));
        else if(str.toLowerCase().endsWith("people")) return str.substring(0, str.toLowerCase().lastIndexOf("ople")) + "rson";
        else return str;
    }

    /**
     *
     * @param str
     * @return true is the singular form of a word should end with the letter "e"
     */
    private boolean shouldEndWithE(String str)
    {
        if(str.toLowerCase().endsWith("s")) str = str.substring(0, str.toLowerCase().lastIndexOf('s'));
        return str.toLowerCase().endsWith("iece")
         || str.toLowerCase().endsWith("ice")
         || str.toLowerCase().endsWith("ace")
         || str.toLowerCase().endsWith("ise")
                ;
    }


And here’s my unit test:


    public void testFromPlural() throws Exception
    {
        assertEquals("car", stringHelper.fromPlural("cars"));
        assertEquals("address", stringHelper.fromPlural("addresses"));
        assertEquals("place", stringHelper.fromPlural("places"));
        assertEquals("piece", stringHelper.fromPlural("pieces"));
        assertEquals("child", stringHelper.fromPlural("children"));
        assertEquals("person", stringHelper.fromPlural("people"));
        assertEquals("Hungry-Child", stringHelper.fromPlural("Hungry-Children"));
        assertEquals("Angry-Person", stringHelper.fromPlural("Angry-People"));
    }


If anybody out there in internet world has had this problem before chime in and I’ll get at’cha. Thanx party people!

(I know the people that typically read blogs like this are not of the partying type but bear with me as I occasionally mix in a bit of slang to keep the reading enjoyable.)

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s