Hi all,
Dims, Tom, Glen, I am {aaron} from Freenode.
Anyway, I am having problems implementing "dynamic type" serialization
under Axis. I can probably best explain what I mean with an example:
Say we have some sort of opaque complex type as input and output
messages to some soap call. Let's also say I'm doing dynamic
invocation. That means I do not have "proper"
serialization/deserialization stubs for the aforementioned opaque
input/output types. Is all lost? No. If I take a Map object, I can
make a best-effort to serialize key/value pairs as elements in the
opaque type. Of course this is not going to be accurate, and without
recursion will only work for one level of nesting, however, it is
probably going to still catch a majority of cases (at least in my
environment).
The problem is, that serialization and deserialization factories and
TypeDescs, are mapped on Class. This renders the above scheme
impossible without some sort of ThreadLocal hacks.
Let's examine. Let's say I create a new custom "bean" DynamicType.
DynamicType, will take a Map object, inspect the map for key/value
pairs, and expose those key/value pairs as ElementDescs in the
TypeDesc it holds. We will have to create a TypeDesc subclass that
can store an explicitly constructed BeanPropertyDescriptor array, as
the default TypeDesc implementation does implicit bean introspection
(which of course will produce the "wrong thing" when introspecting a
Map - it will just produce the interface of the Map object itself).
That is straightforward enough. Since BeanSerializerFactory
dynamically looks up the TypeDesc from the class it is passed, we must
subclass BeanSerializerFactory (let's call it
DynamicSerializerFactory) so that it takes a concrete instance of our
aforementioned DynamicType, initialized with the Map object.
Everything looks good so far - our DynamicSerializer factory will
behave like a BeanSerializerFactory which produces Serializers for
beans whose interface is that provided by the DynamicTypeDesc and
explicit properties inspected in the Map. Sounds good.
But now comes the catch. We have to register this factory based on
the _CLASS_ of input type - DynamicType. However, if we register this
specific factory instance for ALL DynamicType classes, we will
inevitably produce the wrong interface at some point if this mapping
gets overwritten with one initialized with a different concrete Map
object.
The only solution I see is to go ahead and register our
DynamicSerializerFactory, however, instead of keeping a member
instance of DynamicTypeDesc, keep a ThreadLocal instance containing a
DynamicTypeDesc, so that when we are called somewhere down the line in
the invoke process we will produce the correct serializer for the
interface provided by the correct DynamicType for THIS SPECIFIC
invocation.
HOWEVER this is a big hack, and relies on the assumption that the
invocation dispatching thread is the SAME THREAD in which we map the
factory.
So my question is:
1) does this make sense
2) is there any way around it, or better way to implement what I want
that I haven't found
3) does, in fact, the invocation get executed by the same thread as
the caller? (I /think/ so, but I don't want to assume this, as all
sorts of things like thread pools, etc., could potentially be coming
into play)