You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tuscany.apache.org by kelvin goodson <ke...@gmail.com> on 2006/12/08 12:06:58 UTC

[SDO Java] registering generated classes within a scope

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.

Re: [SDO Java] registering generated classes within a scope

Posted by Brent Daniel <br...@gmail.com>.
Kelvin,

  I don't have a strong opinion on which approach to take, but I would
lean towards putting it on the generated Factory. For me, it seems
more intuitive to tell a Factory to register itself into a specifix
context rather than use an SDOUtil method to do the same.

One question, though: is it necessary to return the factory?
registerStaticTypes() does not do this today. My concern is that a
"getFactory()" method in either place does not automatically imply
that registration is taking place.

Brent


On 12/8/06, kelvin goodson <ke...@gmail.com> wrote:
> 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: tuscany-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-dev-help@ws.apache.org


Re: [SDO Java] registering generated classes within a scope

Posted by kelvin goodson <ke...@gmail.com>.
Frank,  I think you are right.  The scenario that sent me along this path
was considering the fairly nasty case of using generated classes for
handling more than one variant of a type system for a given namespace, e.g.
versioning of a type system to provide for additional properties on a type.
However, I made one illogical step.  I was considering that the programmer
might submit an updated schema to the generator with a -package argument
that reflected the schema versioning, but then my error was considering that
there would only be one XXXFactory.INSTANCE, and therefore that we would
need multiple instances of the XXXFactory to control which variant of the
type system was in use. Of course we would have the package discriminator to
reference the factory variants.  It sounds silly when spelled out like
this,  but I think I just hadn't reasoned it out to this extent.  So that
makes it all a lot simpler.

Thanks, Kelvin.

On 08/12/06, Frank Budinsky <fr...@ca.ibm.com> wrote:
>
> 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.
>
> 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.
>
> Frank.
>
> "kelvin goodson" <ke...@gmail.com> 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: tuscany-dev-unsubscribe@ws.apache.org
> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
>
>

Re: [SDO Java] registering generated classes within a scope

Posted by kelvin goodson <ke...@gmail.com>.
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 <en...@gmail.com> wrote:
>
> Hi,
>
> Thanks for the efforts. Please see my comments below.
>
> Thanks,
> Raymond
>
> ----- Original Message -----
> From: "Frank Budinsky" <fr...@ca.ibm.com>
> To: <tu...@ws.apache.org>
> 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" <ke...@gmail.com> 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: tuscany-dev-unsubscribe@ws.apache.org
> > For additional commands, e-mail: tuscany-dev-help@ws.apache.org
> >
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
>
>

Re: [SDO Java] registering generated classes within a scope

Posted by Raymond Feng <en...@gmail.com>.
Hi,

Thanks for the efforts. Please see my comments below.

Thanks,
Raymond

----- Original Message ----- 
From: "Frank Budinsky" <fr...@ca.ibm.com>
To: <tu...@ws.apache.org>
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" <ke...@gmail.com> 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: tuscany-dev-unsubscribe@ws.apache.org
> For additional commands, e-mail: tuscany-dev-help@ws.apache.org
> 


---------------------------------------------------------------------
To unsubscribe, e-mail: tuscany-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-dev-help@ws.apache.org


Re: [SDO Java] registering generated classes within a scope

Posted by Frank Budinsky <fr...@ca.ibm.com>.
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.

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.

Frank.

"kelvin goodson" <ke...@gmail.com> 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: tuscany-dev-unsubscribe@ws.apache.org
For additional commands, e-mail: tuscany-dev-help@ws.apache.org