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?

Reply via email to