|
|
||
David Walend's BlogJune 2006 ArchivesOur Grass is Greenest: OGNL and LINQPosted by dwalend on June 19, 2006 at 12:36 PM | Permalink | Comments (0)About a month ago there was a flurry of blogs about LINQ (Language Integrated Query. I'm not sure what the N stands for.) These articles are a very good description of LINQ, which looks like a useful add-on to the Microsoft CLR family of languages. LINQ would let me wind through layers of getters from the top level, to pluck out just the objects I care about. That's a nice way of saying I feel our usual C#-induced draw of language feature envy. Deja vu followed that feeling of envy. Two years ago I was checking on what some old coworkers from VNP were doing. Drew Davidson and Luke Blanshard had created OGNL, the Object-Graph Navigation Language. OGNL is "an expression language for getting and setting properties of Java objects. You use the same expression for both getting and setting the value of a property." I've been looking for a nail for the OGNL hammer since I saw it. I think the main reason I haven't used OGNL is that writing a big chain of accessors is straightforward (for simple queries), and custom methods to select and build up collections of things inside of classes I control is not hard (for more interesting queries). So unless I force myself to do the (easy) overhead work of adding OGNL to a project, I'll continue to add the (not hard to write) one-off code to get the feature. OGNL was inspired by frustration with commons beanutils' PropertyUtils; Java developers have been sharing this sort of thing for at least five years. We've no reason to feel envy. We just need to get some clue of what we already have, filter out the better ideas, share them and eventually convince the JCP to codify them. I'll also have to regain my waning faith in Sun's process to evolve Java. We've still no bug parade number for my generics RFE. Brilliant Approach to Optional Data Design? Wicked Hack? Source of Horrible Suffering?Posted by dwalend on June 05, 2006 at 07:11 PM | Permalink | Comments (1)I've finally added message selector support for Topics in SomnifugiJMS, a single-process implementation of a Java Messaging Service. It's SomnifugiJMS's 14th alpha release. (Message selectors for Queues will be more difficult, but is the last piece keeping SomnifugiJMS in alpha releases. I think I can get it to work with j.u.c.Conditions and some extra work, but haven't had the time to design it yet.) At JavaOne, I met up with Linda Schneider, one of the key people working on https://mq.dev.java.net/, at JavaOne. She sent me a pointer to the message selector implementation in the JMS reference implementation. The JMS RI just switched to CDDL, which is a file-based license, so I picked up their code, edited it to play nice with my own, and now have message selectors for Topics. They even have a good set of tests in a main method; the JMS RI predates JUnit by a year or so.The only snag I hit was that I use member fields in SomniMessage to hold information that every message should hold, but the JMS RI Selector API expects a Map.
My first thought was to recode the JMS RI Selector to use javax.jms.Message-specific getters. That sounded tedious; I'm not familiar with the code, and am not overly interested in writing or modifying an SQL92 parser. Linda emailed, "[Selector.java is] huge because there is a lot of different items to parse," which seems to say it all. My second thought was to recode SomniMessage to use a Map to store this sort of information. In SomnifugiJMS these fields always have some value, so a Map just seems wrong. SomnifugiJMS is supposed to be faster and simpler than database JMS implementations, especially for small-scale work (which rarely needs message selectors). I didn't want to loose that simplicity to get the message selectors working. I pondered a bit and came up with a third option: use reflection to implement a Map that calls getters when given a field name as a key:
I could implement a general purpose put() method by slipping another Map inside this one, and delegating put()s and get()s to that map for keys that hasGetters does not have. I can't implement the whole Map interface this way because there's no way to remove arbitrary keys. What would removing a field even mean? I think that's an interesting piece of code, especially given the talk of invokeDynamic's evil partner, "changing the members of an object," at a JavaOne talk. It's an interesting choice for sometimes-optional fields when designing data structures. However, "Interesting" might mean that it'll be a source of horrible suffering.
First, code that works this way will have to have Second, the keys are Strings, so there's no great way to predict what might be a key. For message selectors, I know from the JMS specification that the keys will be a small, defined set of Strings that happen to match method names. Perhaps an Enum of possible keys would better define the universe of possible optional members, but that shifts back toward the unsatisfying "this member hasn't been set yet" pattern for accessors. I can live with these problems in my own code, but I want to know these land mines are out there, especially after a decade of trying to avoid using nulls as magic error codes. In my ears: Beethoven's Missa Solimnis. Wow. | ||
|
|