Frank.
"kelvin goodson" <[EMAIL PROTECTED]> wrote on 12/08/2006 06:06:58
AM:
I've been thinking about this issue (
http://issues.apache.org/jira/browse/TUSCANY-684) and plan to work on
it.
Here are some thoughts
In summary, we want to be able to hold and access type definitions,
expressed in terms of generated java classes, within the context of a
type
scoping artifact.
So first a few invariants about how I think this should work, and then
I'd
like to solicit input on some options.
1) We use the tuple of (XXXFactory.class,HelperContext instance) to
get-or-create an instance of the generated XXXFactory class
implementation.
For every invocation of the Factory access method with a given
XXXFactory.class,HelperContext pair, the same instance of XXXFactoryImpl
is
returned.
2) After invoking the factory access methods, using the TypeHelper
instance
associated with the HelperContext instance to create a DataObject in the
namespace of the factory would return an instance of a generated class
3) We deprecate SDOUtil.registerStaticTypes(Class)
So what I'm not yet convinced about is
1) where the interface to the function should sit and
2) where we maintain the state that maps the
(XXXFactory.class,HelperContext
instance) tuple to an XXXFactoryImpl instance
In terms of where the function should sit, I think our choices in the
absence of guidance from the spec is either on SDOUtil or on the
generated
classes themselves. Either of these choices have their upsides and
downsides.
Considering first the housing of the function on SDOUtil. We might
imagine
a method such as
class SDOUtil {
...
public static Factory getFactory(Class factoryInterface,
HelperContext
scope)
}
This method would examine state (wherever that may be housed) to see if
a
Factory for the namespace and within the scope already exists, and if so
it
would return it, if not it would create the factory, update the state
to
reference the newly created factory, and return the new factory
The issues here are that
1) we don't currently have an abstract "Factory" artifact in our
interface
(We have the FactoryBase impl class, but the most concrete artifact in
the
inhertance scheme of things that is currently designed for user
consumption
is java.lang.Object)
2) every call to this method is going to require a cast to the specific
XXXFactory before anything can be done
We could avoid both these issues by housing the factory get-or-create
method
on a generated artifact, e.g.
interface XXXFactory_InterfaceOfSomeSort {
public XXXFactory getFactory(HelperContext scope);
}
or class XXXFactory_ClassOfSomeSort {
static XXXFactory getFactory(HelperContext scope);
}
We could use the interface approach, and use the existing static
XXXFactory
INSTANCE as the object which the user can bootstrap Factory creation
with (
XXXFactory.INSTANCE.getFactory(scope)) but we are trying to move away
from
dependencies on static INSTANCEs (should we be aiming to deprecate the
generated static INSTANCEs in this update?)
We could use the class approach, and use a static method on the
exisiting
XXXFactoryImpl (XXXFactoryImpl.getFactory(scope)) but it's ugly
requiring
the user to import an impl class
We could introduce a new generated Helper type class per Factory to
house
the static method, e.g.
public class XXXFactoryHelper {
public static XXXFactory getFactory(HelperContext scope)
}
so that the user's code would look fairly clean
XXXFactory xFac = XXXFactoryHelper.getFactory(scope);
Of the generated artifact approaches, I like the last example best.
We could use both approaches, and give the user the choice. The SDOUtil
method would just delegate to the generated artifact method.
The second issue is where to house the state that holds the mapping
between
the tuple and the factory instance. It seems to me that there are two
reasonable choices
1) in the HelperContext instance, as a hashmap from namespace to Factory
instance, or
2) in static state associated with the generated classes, as a hashmap
from
HelperContext instance to XXXFactory
I favour (1) quite strongly, as I see the HelperContext as an
instrument of
placing control of concurrency and class loader issues firmly in the
hands
of the user.
Assuming (1) it may be worth giving the implementation issue of exacly
where
with the HelperContext and it's associated helpers this state is
maintained
(or course if we ensure the implementation doesn't leak then we have
flexibility to change this in the light of spec updates)
It might seem natural to put it in the TypeHelperImpl, but TypeHelper
is a
spec artifact that ought to stay language neutral, so clouding the impl
with
Java considerations is not perhaps a good move. We could try to second
guess the spec and create a JavaHelperImpl to house the state, but that
would be its only function currently, so my thoughts are that I will
house
the state directly in the HelperContextImpl for now, and move it if and
when it logically becomes part of a specified artifact.
I'll give this a while for some feedback, and in the meantime I'm going
to
explore / prototype the the combination of
SDOUtil.getFactory(Class, HelperContext) with housing the Factory
instance
mappings in the HelperContext. This would seem an OK approach, since I
think little or no effort will wasted if anyone comes up with a
convincing
argument that we should take alternative elements of my proposition, or
something completely different.
Regards, Kelvin.
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]