I have just resolved TUSCANY-684.  The outcome is that the preferred pattern
for registering a static class suite is

  HelperContext scope = .......;
  XXXFactory.INSTANCE.register(scope);

In doing this I have
1) deprecated SDOUtil.registerStaticTypes()
2) Added an introspectable generation pattern version string to generated
classes to accomodate for compatibility issues in the future (currently I
have set this string to "1.0" in the absence of any better ideas,  I guess
we have a while to discuss the relative merits of the format of this string
if anyone has any ideas)
3) added commentary to the factory implementation, documenting the options
that were in force at the time of generation
4) Added another manual step to regenerating the built in models

The reason for update 4) is that currently the generator automatically adds
dependencies to every Factory on SDOFactory and ModelFactory (including
ModelFactory).  This gives a nested call to registerStaticTypes on
ModelFactory.class.  In the inner call the ModelFactory class has a state
of(isInited=true,INSTANCE=null) and so the new code in the inner call to
registerstaticTypes attempts to operate on a null pkg, and was reporting a
(benign) null pointer exception. Once back in the outer call to
registerStaticTypes the class state is
(isInited=true,INSTANCE=aTrueModelFactoryInstance>) and so the registration
completes successfully.  I think we need to look at whether these default
dependencies need to be generated now, or whether there is a better way to
ensure that the built-in models are always available if we simply go and use
a generated class without somehow else triggering the registration of built
in models first.

--

Kelvin.

On 08/12/06, Raymond Feng <[EMAIL PROTECTED]> wrote:

Hi,

Thanks for the efforts. Please see my comments below.

Thanks,
Raymond

----- Original Message -----
From: "Frank Budinsky" <[EMAIL PROTECTED]>
To: <[email protected]>
Sent: Friday, December 08, 2006 3:30 PM
Subject: Re: [SDO Java] registering generated classes within a scope


> Hi Kelvin,
>
> Could you explain why you think invariant #1 is required? I don't
believe
> we need a Factory instance per context. In fact, we really don't want to
> have multiple copies of the same metadata - there's only one Java Class
> for a type, so we shouldn't have multiple SDO Type instances for it
> either. All we need is to change the Factory to not automatically
register
> itself in the global registry on creation and instead provide a way to
> have the Factory register its metadata in a specific context. Maybe a
> method on a generated Factory interface, e.g.,
> MyFactory.register(HelperContext context). The same Factory can be
> registered in multiple contexts. We're really just trying to control
> visibility to the types.
>

I agree with Frank, we just need a way to make the static types available
in
a given instance of HelperContext. The generated factory should have a
method like:

void register(HelperContext context);

And then in the SCA case, the import.sdo loader will call this API to
register the generated types to the instance of HelperContext associated
with the owning composite.

> We'll also want to provide a way to associate contexts with
ClassLoaders,
> because you can't have more than one generated implementation of the
same
> class in the same ClassLoader scope, but how we chain/compose contexts
> and/or associate them with ClassLoaders is a separate issue.
>

I agree it's a separate issue. Do we have any thoughts to support the
delegation across HelperContext(s)? For example, making HC1, HC2 visible
to
HC3?

> 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]
>


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]


Reply via email to