Interceptors implement a generic interface that is parameterized over a subclass of Message. Each interceptor class implements handleMessage(T), where 'T extends Message'.
This removes one type cast from the interceptors, but it creates certain risks. I hit one of them, and I've been thinking about whether we want to change anything. Nothing checks to ensure that the actual message being processed is type-compatible with each of the interceptors. If someone puts, for example, an Interceptor<SoapMessage> into a chain, and an XMLMessage comes along, the result will be a ClassCastException. It will be an especially confusing ClassCastException, due to type erasure. Interceptor declares handleMessage(T), but by the time type erasure is done, that's just handleMessage(Message). When a mistyped message comes along, this mismatch is detected when code tries to assign it to the parameter, and the backtrace claims that the exception is being thrown by line one of the overall source file. I could think of two alternatives (other than leaving well enough alone). Alternative 1: get rid of the whole generic structure in interceptors. Everybody handles Message, and casts as they need to based on their assumptions or knowledge of the situation. Alternative 2: the chain filters out mis-types interceptors, making the type of the message a condition on whether the interceptor fires or not. While #1 might have something to be said for it in pure hindsight, it would be quite disruptive to all those user-written interceptors out there, so let's forget it. #2 has some attractive characteristics. It would work like this, I think. Interceptor<T> would gain a method: Class<? extends Message> getMessageClass(); Each interceptor would return the message type it's prepared to handle. The chain would skip messages that didn't qualify. Does anyone think this is worth doing?