You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avalon.apache.org by Leo Sutic <le...@inspireinfrastructure.com> on 2002/12/08 00:17:07 UTC

[PROPOSAL] Context Defined

All,

the Context interface and its associated stage - Contextualizable - has 
been the subject of much controversy. As a matter of fact, I'd say that it 
is the single most controversial subject we have in Framework, and I'd like 
to propose a way where I think the conflicting viewpoints can be 
accomodated, although this will require some compromise.

                               -oOo-

First, there are two ways to view a context:

  1) What I'll call the "Merlin" way, assumes that the context is an 
unmodifiable map of constant, read-only data.

  2) What I'll call the "Phoenix" way, extends the Merlin way by also 
allowing operations in the Context, such as requestShutdown(). The Context 
is here not just a source of deployment information, but also a link 
through which the component may communicate with its container.


Second, the differences has given rise to two groups with differing viewpoints:

  1) The goal of the Merlin group is component portability.

  2) The goal of the Phoenix group is to be able to extend the Context as 
needed - for example to turn it into a servlet context, ejb context, etc.

The *interests* of both groups are, I believe, to avoid having their code 
become obsolete - a pure Phoenix approach would make the goal of component 
portability unattainable, while a pure Merlin approach would make Phoenix 
as it is now impossible.

Thus, any solution must be able to accomodate the current usage within 
Phoenix, while still making component portability a 
possibility.  Specifically, any code that can't capture the usage pattern 
in Phoenix is, in my opinion, dead on arrival.

I don't think it is possible to accomodate both sides 100%, but I do think 
it is possible to have a solution where the Phoenix usage pattern is 
allowed, while still keeping component portability for all practical 
purposes. This means not 100% portability, but with very few cases of 
non-portability, and a clear description of what is required for 100% 
portability.

                               -oOo-

I'll focus on two things:

  1) How does a component specify what context it requires?

  2) How is this provided by the container?


SPECIFICATION
-------------

A brief overview of how it is currently solved (as I understand it):

Both cases:
The component can specify any key-value mappings it will access via the 
Context.get method. The specification includes the key, optionally a name 
translation meaning that you can, for example, access "avalon:work" through 
the key "work", and a class name indicating the type of the value.

As for the actual type of the context instance being given to the component:

Merlin:
The component specifies a context class C. That class is instantiated with 
the  constructor taking one Context parameter. This instance is then given 
to the component. (This was as I understood it from Stephen's emails, I 
haven't found any code doing this in the assembly or meta packages, so I 
might be way off here.)

Phoenix:
A BlockContext implementation is given directly to the component. No way 
for the component to specify any other class.


Note that both containers completely solve the problem so far as to having 
a way to specify the expected key-value mappings accessible in the Context.

What is needed is a way to specify what methods should be avilable in 
addition to a way to specify key-value mappings accessible via the 
Context.get method. This is needed in order to be able to capture the 
Phoenix BlockContext interface. With both meta-models, you can specify a 
requirement for any key K to map to an object of any type V, and using the 
standardized context keys, you can specify the meaning of the value V. 
However, neither allows you to require a method called requestShutdown() 
that requests a shutdown. While Merlin allows you to specify an 
implementation class, that method can not be used to provide a BlockContext.


What I intend to add is the following:

  + A way to specify what mehods are required in the context.

  + A restriction on what methods may be required while still remaining 
100% Avalon compatible.


How to Specify Methods:

The component will declare one class name designating an interface. This 
can be done like this:

     <context>
         <require-interface name="org.apache.avalon.phoenix.BlockContext"/>
     </context>

This indicates that the context object being passed to contextualize() must 
be cast-able to a BlockContext. This is read as: "The component requires 
that all methods in the BlockContext interface is present in the context, 
and that the context object given can be casted to a BlockContext."


A Restriction on Methods:

There will be a set of standard interfaces in Framework. Any component may 
request any union of those interfaces. For example, if we have in framework:

     interface WorkDirectoryContext {
         public File getWorkDirectory ();
     }

     interface ContextDirectoryContext {
         public File getContextDirectory ();
     }

A component may have an interface:

     interface MyContextInterface
         extends ContextDirectoryContext,
                 WorkDirectoryContext
     {};

And may specify that interface:

     <context>
         <require-interface name="org.example.MyContextInterface"/>
     </context>

And can expect to have the request fulfilled in any 100% Avalon container. 
(Alternatively we can limit interfaces to Avalon Micro Edition, SE, or EE, 
depending on the profiles we come up with for the übercontainer.)  Note 
that this does in no way exclude specifying key-value pair requirements. A 
component can specify key-value pairs, an interface, both or neither.

A final restriction on the methods are that the method signatures must be 
unique. That is, if we in framework have two interfaces:

     interface WorkDirectoryContext {
         public File getDirectory ();
     }

     interface ContextDirectoryContext {
         public File getDirectory ();
     }

With identical signatures, a union of those interfaces

     interface MyContextInterface
         extends ContextDirectoryContext,
                 WorkDirectoryContext
     {};

will only have one method, and furthermore it is *impossible* to determine 
through which interface a call was made. That is:

     MyContextInterface mci = ...;

     // These two method calls are indistinguishale.
     // There is no way, even with dynamic proxies,
     // for the mci object to know whether the context
     // directory or the work directory should be returned.
     ((WorkDirectoryContext) mci).getDirectory ();
     ((ContextDirectoryContext) mci).getDirectory ();

We can ease that restriction by only requiring method signatures in the 
interfaces in Framework to be unique, but this would make it harder to 
promote a method into Framework. Obvious conclusion: these context 
interfaces should be kept to a minimum.


What we allow in Framework:

It is my view that the methods in Framework should be limited to simple 
data-access methods, such as getWorkDirectory and getContextDirectory, and 
that methods such as requestShutdown should be left out. The reasoning 
behind this is as follows:

  + There is major controversy regarding the exposure of services, such as 
requestShutdown (in particular that one).

  + Few components in Phoenix uses that method.

  + In fact, I think most Phoenix blocks only use the getContextDirectory 
method.

  + Therefore, we can lower the requirements on those blocks, thus making 
them portable.

  + For the few blocks that *do* require a requestShutdown or similar, they 
can declare a requirement of BlockContext.

  + Those few blocks will remain non-portable, but I guess they are so few 
that it doesn't matter.

Also, it is my opinion that:

  + Addition of a context interface to Framework should be via consensus vote.

  + Domain-specific contexts, such as EJB contexts and servlet contexts, 
should not be allowed into Framework, as neither EJBs nor Servlets are 
Avalon components.

                               -oOo-


PROVIDING A CONTEXT
-------------------

In the previos section I established that a component may place two types 
of requirements on a context:

  1) Key-value mappings.

  2) Methods in the context interface.

How to provide (1) is a solved problem and there is concensus on it.

As for (2), I expect the container to have some class that implements Context:

     class ContextImpl implements Context { ... }

That class should implement *all* Framework-level interfaces:

     class ContextImpl implements Context,
         WorkDirectoryContext, ContextDirectoryContext { ... }

It can also implement any other interfaces, but this is trivial:

     class ContextImpl implements Context,
         WorkDirectoryContext,
         ContextDirectoryContext,
         ShutdownContext { ... }

OK, given the above in the container, what happens when a component 
requests a Context interface like this:

     interface MyContextInterface
         extends ContextDirectoryContext,
                 WorkDirectoryContext
     {};

     <context>
         <require-interface name="org.example.MyContextInterface"/>
     </context>

Note the following: Just because ContextImpl implements 
ContextDirectoryContext and WorkDirectoryContext, it does *not* implement 
MyContextInterface. The following code will fail with a ClassCastException:

     ContextImpl impl = new ContextImpl ();
     MyContextInterface mci = (MyContextInterface) impl; // ClassCastException

Thus, we need to use a proxy object implementing the required context 
interface. The process for a container is as follows:

  1. Load the class specified in the <require-interface/> element. In this 
case it is MyContextInterface.
  2. For each MI in the methods in the MyContextInterface interface:
     2.1. Find a method, M, with the same signature in the container's 
(corresponding) ContextImpl class.
     2.2. If a method isn't found, give up and throw an Exception 
(ComponentNotSupported)
     2.3. Otherwise, establish a mapping MI -> M.
  3. Create a dynamic proxy implementing MyContextInterface.
  4. Let the InvocationHandler map every call via the mapping established 
in step 2.
  5. Give this proxy to the component's contextualize() method.

                               -oOo-

Summary:

I have shown a way to declare a context requirement for components that 
captures all current usage patterns, and shown how the requirement can be 
satisfied by a container. The methods shown here can be used to define 
ServletContexts, EJB contexts, etc. as well. In particular, they can be 
used to define the Phoenix BlockContext and the JAMES MailContext. 
Portability suffers a little, but not enough to make it an issue.

/LS


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PROPOSAL] Context Defined

Posted by Stephen McConnell <mc...@apache.org>.

Leo Sutic wrote:

> All,
>
> the Context interface and its associated stage - Contextualizable - 
> has been the subject of much controversy. As a matter of fact, I'd say 
> that it is the single most controversial subject we have in Framework, 
> and I'd like to propose a way where I think the conflicting viewpoints 
> can be accomodated, although this will require some compromise.
>
>                               -oOo-
>
> First, there are two ways to view a context:
>
>  1) What I'll call the "Merlin" way, assumes that the context is an 
> unmodifiable map of constant, read-only data.
>
>  2) What I'll call the "Phoenix" way, extends the Merlin way by also 
> allowing operations in the Context, such as requestShutdown(). The 
> Context is here not just a source of deployment information, but also 
> a link through which the component may communicate with its container.
>
>
> Second, the differences has given rise to two groups with differing 
> viewpoints:
>
>  1) The goal of the Merlin group is component portability.
>
>  2) The goal of the Phoenix group is to be able to extend the Context 
> as needed - for example to turn it into a servlet context, ejb 
> context, etc.
>
> The *interests* of both groups are, I believe, to avoid having their 
> code become obsolete - a pure Phoenix approach would make the goal of 
> component portability unattainable, while a pure Merlin approach would 
> make Phoenix as it is now impossible. 


Leo:

Have to jump in here and say that in general, I'm really not concerned 
about code obselesence on the container side - I am concerned about code 
obselecense on the component side.  As things stand at the moment there 
are aspects of the Merlin containment architecture that I'm using on the 
clinet side - things like  the ability to declare an appliance factory 
(which lets me plug-in auto-CORBA-POA-activation).  Whee possible I'm 
trying to abstract these things out with crearly defined interfaces, 
factories, etc.   Once factoried out - it becomes a lot easier to 
discuss the contract, its implication on a containerment API, and its 
value to the component author.

>
>
> Thus, any solution must be able to accomodate the current usage within 
> Phoenix, while still making component portability a possibility.  
> Specifically, any code that can't capture the usage pattern in Phoenix 
> is, in my opinion, dead on arrival.
>
> I don't think it is possible to accomodate both sides 100%, but I do 
> think it is possible to have a solution where the Phoenix usage 
> pattern is allowed, while still keeping component portability for all 
> practical purposes. This means not 100% portability, but with very few 
> cases of non-portability, and a clear description of what is required 
> for 100% portability.
>
>                               -oOo-
>
> I'll focus on two things:
>
>  1) How does a component specify what context it requires?
>
>  2) How is this provided by the container?
>
>
> SPECIFICATION
> -------------
>
> A brief overview of how it is currently solved (as I understand it):
>
> Both cases:
> The component can specify any key-value mappings it will access via 
> the Context.get method. The specification includes the key, optionally 
> a name translation meaning that you can, for example, access 
> "avalon:work" through the key "work", and a class name indicating the 
> type of the value.
>
> As for the actual type of the context instance being given to the 
> component:
>
> Merlin:
> The component specifies a context class C. That class is instantiated 
> with the  constructor taking one Context parameter. This instance is 
> then given to the component. (This was as I understood it from 
> Stephen's emails, I haven't found any code doing this in the assembly 
> or meta packages, so I might be way off here.) 


The assembly package contains this code.
project: avalon-sandbox/assembly,
package: org.apache.avalon.assembly.lifecycle.ContextHandler

  try
  {
      Constructor constructor = clazz.getConstructor(
         new Class[]{Map.class, Context.class} );
      result = (Context)constructor.newInstance( new Object[]{map, null} );
  }
  catch( Throwable e )
  {
      throw new ContextException(
        "Unexpected exception while creating context form "
        + classname, e );
  }

This simply creates an instance of a context class (e.g. 
DefaultBlockContext) and instantiates it.  The remainder of the code is 
concerned with the population of the context entries.  The ideas I've 
talked about under the locator thread would enable this to be seperated 
out into one of many plug-in strategies.

>
>
> Phoenix:
> A BlockContext implementation is given directly to the component. No 
> way for the component to specify any other class.
>
>
> Note that both containers completely solve the problem so far as to 
> having a way to specify the expected key-value mappings accessible in 
> the Context.
>
> What is needed is a way to specify what methods should be avilable in 
> addition to a way to specify key-value mappings accessible via the 
> Context.get method. This is needed in order to be able to capture the 
> Phoenix BlockContext interface. With both meta-models, you can specify 
> a requirement for any key K to map to an object of any type V, and 
> using the standardized context keys, you can specify the meaning of 
> the value V. However, neither allows you to require a method called 
> requestShutdown() that requests a shutdown. While Merlin allows you to 
> specify an implementation class, that method can not be used to 
> provide a BlockContext.


Why not?

Using the existing assembly API, if I (component author) declare that I 
need to narrow an argument to BlockContext - then I need to declare this 
with something like:

   <type>
     <context type="org.apache.avalon.phoenix.BlockContext">
        <!-- add entries here -->
     </context>
   </type>

Then if I (as assembler) declare something like:

    <component name="fred" class="FredsComponent">
        <context class="MyBlockContext">
            <!-- creation directives -->
        </context>
    </component>

End result - the system has everything it needs to provide a 
BlockContext implementation.

Using the locator based strategy this would look like:

   <type>
     <context>
        <locator type="org.apache.avalon.phoenix.BlockContext"/>
     </context>
   </type>

A an assembly directive along the lines of:

   <component name="fred" class="MyComponent"/>

The difference between the current Merlin apprach and the locator 
approach is that the assembly directives are moved out because the 
container will attempt to resolve a service capable of providing locator 
services supporting BlockContext.

>
>
> What I intend to add is the following:
>
>  + A way to specify what mehods are required in the context.
>
>  + A restriction on what methods may be required while still remaining 
> 100% Avalon compatible.
>
>
> How to Specify Methods:
>
> The component will declare one class name designating an interface. 
> This can be done like this:
>
>     <context>
>         <require-interface 
> name="org.apache.avalon.phoenix.BlockContext"/>
>     </context> 

>
>
> This indicates that the context object being passed to contextualize() 
> must be cast-able to a BlockContext. This is read as: "The component 
> requires that all methods in the BlockContext interface is present in 
> the context, and that the context object given can be casted to a 
> BlockContext."


Yep.

>
>
> A Restriction on Methods:
>
> There will be a set of standard interfaces in Framework. Any component 
> may request any union of those interfaces. For example, if we have in 
> framework:
>
>     interface WorkDirectoryContext {
>         public File getWorkDirectory ();
>     }
>
>     interface ContextDirectoryContext {
>         public File getContextDirectory ();
>     }
>
> A component may have an interface:
>
>     interface MyContextInterface
>         extends ContextDirectoryContext,
>                 WorkDirectoryContext
>     {};
>
> And may specify that interface:
>
>     <context>
>         <require-interface name="org.example.MyContextInterface"/>
>     </context>
>
> And can expect to have the request fulfilled in any 100% Avalon 
> container. (Alternatively we can limit interfaces to Avalon Micro 
> Edition, SE, or EE, depending on the profiles we come up with for the 
> übercontainer.)  Note that this does in no way exclude specifying 
> key-value pair requirements. A component can specify key-value pairs, 
> an interface, both or neither.


If I declare BlockContext - I'm implicitly stating that (a) the suplied 
object is narrawable to any interface in the BlockContext interface 
graph + the supplied object has a bunch of keys defined by BlockContext. 
 The declaration of BlockContext should result in the import of keys 
based on a BlockContext meta and super-type meta.  This ensures that the 
container can import and detect key conflicts.

>
> A final restriction on the methods are that the method signatures must 
> be unique. That is, if we in framework have two interfaces:
>
>     interface WorkDirectoryContext {
>         public File getDirectory ();
>     }
>
>     interface ContextDirectoryContext {
>         public File getDirectory ();
>     }
>
> With identical signatures, a union of those interfaces
>
>     interface MyContextInterface
>         extends ContextDirectoryContext,
>                 WorkDirectoryContext
>     {};
>
> will only have one method, and furthermore it is *impossible* to 
> determine through which interface a call was made. That is:
>
>     MyContextInterface mci = ...;
>
>     // These two method calls are indistinguishale.
>     // There is no way, even with dynamic proxies,
>     // for the mci object to know whether the context
>     // directory or the work directory should be returned.
>     ((WorkDirectoryContext) mci).getDirectory ();
>     ((ContextDirectoryContext) mci).getDirectory ();
>
> We can ease that restriction by only requiring method signatures in 
> the interfaces in Framework to be unique, but this would make it 
> harder to promote a method into Framework. Obvious conclusion: these 
> context interfaces should be kept to a minimum.


This is the reason why I'm thinking about the preference for a single 
locator, or multiple service declarations.  This would work providing 
the locator service meta model supports supertypes. It would keep the 
model simpler - but I'm still thinking - so don;t take my comments as a 
position!

:-)

>
>
> What we allow in Framework:
>
> It is my view that the methods in Framework should be limited to 
> simple data-access methods, such as getWorkDirectory and 
> getContextDirectory, and that methods such as requestShutdown should 
> be left out. The reasoning behind this is as follows:
>
>  + There is major controversy regarding the exposure of services, such 
> as requestShutdown (in particular that one).
>
>  + Few components in Phoenix uses that method.
>
>  + In fact, I think most Phoenix blocks only use the 
> getContextDirectory method.
>
>  + Therefore, we can lower the requirements on those blocks, thus 
> making them portable.
>
>  + For the few blocks that *do* require a requestShutdown or similar, 
> they can declare a requirement of BlockContext.
>
>  + Those few blocks will remain non-portable, but I guess they are so 
> few that it doesn't matter.
>
> Also, it is my opinion that:
>
>  + Addition of a context interface to Framework should be via 
> consensus vote.
>
>  + Domain-specific contexts, such as EJB contexts and servlet 
> contexts, should not be allowed into Framework, as neither EJBs nor 
> Servlets are Avalon components.


I really don't see the need for any clinet side context interfaces in 
framework beyond the existing Context and maybe one standard interface 
AvalonContext (which basically provides a name and a working directory) 
- I do see the need for a standard interface for a component that can 
provide objects by key (e.g. Locator) that may or may not be exposed 
directly to the client. The locator approach seperates the issue of how 
a context constraint is supported as district from convinience 
interfaces.  It also removes the issue of context as behavioural as 
opposed to context as a map.

>
>                               -oOo-
>
>
> PROVIDING A CONTEXT
> -------------------
>
> In the previos section I established that a component may place two 
> types of requirements on a context:
>
>  1) Key-value mappings.
>
>  2) Methods in the context interface.
>
> How to provide (1) is a solved problem and there is concensus on it. 


There are solutions - I would not call it concensus - I think there is 
more to think about on the meta side - but yes, it's the easy side of 
the equation.

>
>
> As for (2), I expect the container to have some class that implements 
> Context:
>
>     class ContextImpl implements Context { ... }
>
> That class should implement *all* Framework-level interfaces:
>
>     class ContextImpl implements Context,
>         WorkDirectoryContext, ContextDirectoryContext { ... }
>
> It can also implement any other interfaces, but this is trivial:
>
>     class ContextImpl implements Context,
>         WorkDirectoryContext,
>         ContextDirectoryContext,
>         ShutdownContext { ... }
>
> OK, given the above in the container, what happens when a component 
> requests a Context interface like this:
>
>     interface MyContextInterface
>         extends ContextDirectoryContext,
>                 WorkDirectoryContext
>     {};
>
>     <context>
>         <require-interface name="org.example.MyContextInterface"/>
>     </context>
>
> Note the following: Just because ContextImpl implements 
> ContextDirectoryContext and WorkDirectoryContext, it does *not* 
> implement MyContextInterface. The following code will fail with a 
> ClassCastException:
>
>     ContextImpl impl = new ContextImpl ();
>     MyContextInterface mci = (MyContextInterface) impl; // 
> ClassCastException
>
> Thus, we need to use a proxy object implementing the required context 
> interface. The process for a container is as follows:
>
>  1. Load the class specified in the <require-interface/> element. In 
> this case it is MyContextInterface.
>  2. For each MI in the methods in the MyContextInterface interface:
>     2.1. Find a method, M, with the same signature in the container's 
> (corresponding) ContextImpl class.
>     2.2. If a method isn't found, give up and throw an Exception 
> (ComponentNotSupported)
>     2.3. Otherwise, establish a mapping MI -> M.
>  3. Create a dynamic proxy implementing MyContextInterface.
>  4. Let the InvocationHandler map every call via the mapping 
> established in step 2.
>  5. Give this proxy to the component's contextualize() method.
>
>                               -oOo-
>
> Summary:
>
> I have shown a way to declare a context requirement for components 
> that captures all current usage patterns, and shown how the 
> requirement can be satisfied by a container. The methods shown here 
> can be used to define ServletContexts, EJB contexts, etc. as well. In 
> particular, they can be used to define the Phoenix BlockContext and 
> the JAMES MailContext. Portability suffers a little, but not enough to 
> make it an issue.


I think we are on a very similar track - several things I'm thinking 
about and not enough time right now to put down words - but I'll come 
back to this a little later.

Cheers, Steve.

>
> /LS
>
>
> -- 
> To unsubscribe, e-mail:   
> <ma...@jakarta.apache.org>
> For additional commands, e-mail: 
> <ma...@jakarta.apache.org>
>
>
>

-- 

Stephen J. McConnell

OSM SARL
digital products for a global economy
mailto:mcconnell@osm.net
http://www.osm.net




--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PROPOSAL] Context Defined

Posted by Peter Donald <pe...@realityforge.org>.
On Sun, 8 Dec 2002 14:42, Chad Stansbury wrote:
> I'm not sure if I'm on the right track or not, but so far I've implemented
> a pretty decent SocketServer and HttpServer (both NIO-based) that work
> pretty well in such an architecture.  If you'd like to hear more about it,
> I'll share more of my work with the group, otherwise I'll just go back to
> my lurking...

Sure - hearing about it would be great. In particular I would be interested in 
what exactly goes into various contexts - particularly StartupContext, 
ShutdownContext and DestroyContext.


-- 
Cheers,

Peter Donald
---------------------------------------------------
"Wise men don't need advice. Fools don't take it." 
                        -Benjamin Franklin 
--------------------------------------------------- 


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PROPOSAL] Context Defined

Posted by Chad Stansbury <st...@earthlink.net>.
I'm a lurker on this group, who has been playing around with 
component-oriented architectures, and for what it's worth, this is what I've 
found most useful...  I've created 6 main contexts (all interfaces) - they 
are: InitialContext, ConfigurationContext, StartupContext, RuntimeContext, 
ShutdownContext, and DestroyContext.  All contexts define operations that 
*tell* the developer what they can do at that time - for example, you can't 
attempt to locate another component until the StartupContext.

This leads to a component definition of:  

interface Component
{
	public void initialize(InitialContext);
	public void configure(ConfigurationContext);
	public void startup(StartupContext);
	public void shutdown(ShutdownContext);
	public void destroy(DestroyContext);
}

I'm not sure if I'm on the right track or not, but so far I've implemented a 
pretty decent SocketServer and HttpServer (both NIO-based) that work pretty 
well in such an architecture.  If you'd like to hear more about it, I'll 
share more of my work with the group, otherwise I'll just go back to my 
lurking...

Chad

On Saturday 07 December 2002 04:17 pm, Leo Sutic wrote:
> All,
>
> the Context interface and its associated stage - Contextualizable - has
> been the subject of much controversy. As a matter of fact, I'd say that it
> is the single most controversial subject we have in Framework, and I'd like
> to propose a way where I think the conflicting viewpoints can be
> accomodated, although this will require some compromise.
>
>                                -oOo-
>
> First, there are two ways to view a context:
>
>   1) What I'll call the "Merlin" way, assumes that the context is an
> unmodifiable map of constant, read-only data.
>
>   2) What I'll call the "Phoenix" way, extends the Merlin way by also
> allowing operations in the Context, such as requestShutdown(). The Context
> is here not just a source of deployment information, but also a link
> through which the component may communicate with its container.
>
>
> Second, the differences has given rise to two groups with differing
> viewpoints:
>
>   1) The goal of the Merlin group is component portability.
>
>   2) The goal of the Phoenix group is to be able to extend the Context as
> needed - for example to turn it into a servlet context, ejb context, etc.
>
> The *interests* of both groups are, I believe, to avoid having their code
> become obsolete - a pure Phoenix approach would make the goal of component
> portability unattainable, while a pure Merlin approach would make Phoenix
> as it is now impossible.
>
> Thus, any solution must be able to accomodate the current usage within
> Phoenix, while still making component portability a
> possibility.  Specifically, any code that can't capture the usage pattern
> in Phoenix is, in my opinion, dead on arrival.
>
> I don't think it is possible to accomodate both sides 100%, but I do think
> it is possible to have a solution where the Phoenix usage pattern is
> allowed, while still keeping component portability for all practical
> purposes. This means not 100% portability, but with very few cases of
> non-portability, and a clear description of what is required for 100%
> portability.
>
>                                -oOo-
>
> I'll focus on two things:
>
>   1) How does a component specify what context it requires?
>
>   2) How is this provided by the container?
>
>
> SPECIFICATION
> -------------
>
> A brief overview of how it is currently solved (as I understand it):
>
> Both cases:
> The component can specify any key-value mappings it will access via the
> Context.get method. The specification includes the key, optionally a name
> translation meaning that you can, for example, access "avalon:work" through
> the key "work", and a class name indicating the type of the value.
>
> As for the actual type of the context instance being given to the
> component:
>
> Merlin:
> The component specifies a context class C. That class is instantiated with
> the  constructor taking one Context parameter. This instance is then given
> to the component. (This was as I understood it from Stephen's emails, I
> haven't found any code doing this in the assembly or meta packages, so I
> might be way off here.)
>
> Phoenix:
> A BlockContext implementation is given directly to the component. No way
> for the component to specify any other class.
>
>
> Note that both containers completely solve the problem so far as to having
> a way to specify the expected key-value mappings accessible in the Context.
>
> What is needed is a way to specify what methods should be avilable in
> addition to a way to specify key-value mappings accessible via the
> Context.get method. This is needed in order to be able to capture the
> Phoenix BlockContext interface. With both meta-models, you can specify a
> requirement for any key K to map to an object of any type V, and using the
> standardized context keys, you can specify the meaning of the value V.
> However, neither allows you to require a method called requestShutdown()
> that requests a shutdown. While Merlin allows you to specify an
> implementation class, that method can not be used to provide a
> BlockContext.
>
>
> What I intend to add is the following:
>
>   + A way to specify what mehods are required in the context.
>
>   + A restriction on what methods may be required while still remaining
> 100% Avalon compatible.
>
>
> How to Specify Methods:
>
> The component will declare one class name designating an interface. This
> can be done like this:
>
>      <context>
>          <require-interface name="org.apache.avalon.phoenix.BlockContext"/>
>      </context>
>
> This indicates that the context object being passed to contextualize() must
> be cast-able to a BlockContext. This is read as: "The component requires
> that all methods in the BlockContext interface is present in the context,
> and that the context object given can be casted to a BlockContext."
>
>
> A Restriction on Methods:
>
> There will be a set of standard interfaces in Framework. Any component may
> request any union of those interfaces. For example, if we have in
> framework:
>
>      interface WorkDirectoryContext {
>          public File getWorkDirectory ();
>      }
>
>      interface ContextDirectoryContext {
>          public File getContextDirectory ();
>      }
>
> A component may have an interface:
>
>      interface MyContextInterface
>          extends ContextDirectoryContext,
>                  WorkDirectoryContext
>      {};
>
> And may specify that interface:
>
>      <context>
>          <require-interface name="org.example.MyContextInterface"/>
>      </context>
>
> And can expect to have the request fulfilled in any 100% Avalon container.
> (Alternatively we can limit interfaces to Avalon Micro Edition, SE, or EE,
> depending on the profiles we come up with for the übercontainer.)  Note
> that this does in no way exclude specifying key-value pair requirements. A
> component can specify key-value pairs, an interface, both or neither.
>
> A final restriction on the methods are that the method signatures must be
> unique. That is, if we in framework have two interfaces:
>
>      interface WorkDirectoryContext {
>          public File getDirectory ();
>      }
>
>      interface ContextDirectoryContext {
>          public File getDirectory ();
>      }
>
> With identical signatures, a union of those interfaces
>
>      interface MyContextInterface
>          extends ContextDirectoryContext,
>                  WorkDirectoryContext
>      {};
>
> will only have one method, and furthermore it is *impossible* to determine
> through which interface a call was made. That is:
>
>      MyContextInterface mci = ...;
>
>      // These two method calls are indistinguishale.
>      // There is no way, even with dynamic proxies,
>      // for the mci object to know whether the context
>      // directory or the work directory should be returned.
>      ((WorkDirectoryContext) mci).getDirectory ();
>      ((ContextDirectoryContext) mci).getDirectory ();
>
> We can ease that restriction by only requiring method signatures in the
> interfaces in Framework to be unique, but this would make it harder to
> promote a method into Framework. Obvious conclusion: these context
> interfaces should be kept to a minimum.
>
>
> What we allow in Framework:
>
> It is my view that the methods in Framework should be limited to simple
> data-access methods, such as getWorkDirectory and getContextDirectory, and
> that methods such as requestShutdown should be left out. The reasoning
> behind this is as follows:
>
>   + There is major controversy regarding the exposure of services, such as
> requestShutdown (in particular that one).
>
>   + Few components in Phoenix uses that method.
>
>   + In fact, I think most Phoenix blocks only use the getContextDirectory
> method.
>
>   + Therefore, we can lower the requirements on those blocks, thus making
> them portable.
>
>   + For the few blocks that *do* require a requestShutdown or similar, they
> can declare a requirement of BlockContext.
>
>   + Those few blocks will remain non-portable, but I guess they are so few
> that it doesn't matter.
>
> Also, it is my opinion that:
>
>   + Addition of a context interface to Framework should be via consensus
> vote.
>
>   + Domain-specific contexts, such as EJB contexts and servlet contexts,
> should not be allowed into Framework, as neither EJBs nor Servlets are
> Avalon components.
>
>                                -oOo-
>
>
> PROVIDING A CONTEXT
> -------------------
>
> In the previos section I established that a component may place two types
> of requirements on a context:
>
>   1) Key-value mappings.
>
>   2) Methods in the context interface.
>
> How to provide (1) is a solved problem and there is concensus on it.
>
> As for (2), I expect the container to have some class that implements
> Context:
>
>      class ContextImpl implements Context { ... }
>
> That class should implement *all* Framework-level interfaces:
>
>      class ContextImpl implements Context,
>          WorkDirectoryContext, ContextDirectoryContext { ... }
>
> It can also implement any other interfaces, but this is trivial:
>
>      class ContextImpl implements Context,
>          WorkDirectoryContext,
>          ContextDirectoryContext,
>          ShutdownContext { ... }
>
> OK, given the above in the container, what happens when a component
> requests a Context interface like this:
>
>      interface MyContextInterface
>          extends ContextDirectoryContext,
>                  WorkDirectoryContext
>      {};
>
>      <context>
>          <require-interface name="org.example.MyContextInterface"/>
>      </context>
>
> Note the following: Just because ContextImpl implements
> ContextDirectoryContext and WorkDirectoryContext, it does *not* implement
> MyContextInterface. The following code will fail with a ClassCastException:
>
>      ContextImpl impl = new ContextImpl ();
>      MyContextInterface mci = (MyContextInterface) impl; //
> ClassCastException
>
> Thus, we need to use a proxy object implementing the required context
> interface. The process for a container is as follows:
>
>   1. Load the class specified in the <require-interface/> element. In this
> case it is MyContextInterface.
>   2. For each MI in the methods in the MyContextInterface interface:
>      2.1. Find a method, M, with the same signature in the container's
> (corresponding) ContextImpl class.
>      2.2. If a method isn't found, give up and throw an Exception
> (ComponentNotSupported)
>      2.3. Otherwise, establish a mapping MI -> M.
>   3. Create a dynamic proxy implementing MyContextInterface.
>   4. Let the InvocationHandler map every call via the mapping established
> in step 2.
>   5. Give this proxy to the component's contextualize() method.
>
>                                -oOo-
>
> Summary:
>
> I have shown a way to declare a context requirement for components that
> captures all current usage patterns, and shown how the requirement can be
> satisfied by a container. The methods shown here can be used to define
> ServletContexts, EJB contexts, etc. as well. In particular, they can be
> used to define the Phoenix BlockContext and the JAMES MailContext.
> Portability suffers a little, but not enough to make it an issue.
>
> /LS


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: [PROPOSAL] Context Defined

Posted by "Noel J. Bergman" <no...@devtech.com>.
> On Mon, 9 Dec 2002 13:47, Noel J. Bergman wrote:
> > > Assume that we ignore syntactic sugar and access data via "well
defined"
> > > entrys. So rather than
> > > ((FooContext)context).getFooDirectory()
> > > we use
> > > (File)context.get( "foo:directory" );
> > Those are not equivalent.
> from a components point of view they are. One is syntactic sugar for the
> other.

No they are not.  In the former case, my client code has a declared
dependency on something called FooContext for reasons having nothing to do
with what I actually wish to accomplish.  In the latter case, all I my class
depends upon is the basic Context interface, and the desired object type:
File.  I do not care HOW I get the File object that represents a directory.
I could not care less about some "FooContext", "BarContext", or ... in this
case ... what is apparently a FUBarContext.

> > In the former case, context IS-A FooContext.  In
> > the latter case, context need only HAVE-A FooContext (perhaps).
> I am sure most people here are comfortable with the difference
> between these concepts.

I am certainly hoping that your assertion is correct, but at the moment,
you'd be hard pressed to prove it.

	--- Noel


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PROPOSAL] Context Defined

Posted by Peter Donald <pe...@realityforge.org>.
On Mon, 9 Dec 2002 13:47, Noel J. Bergman wrote:
> > Assume that we ignore syntactic sugar and access data via "well defined"
> > entrys. So rather than
> > ((FooContext)context).getFooDirectory()
> > we use
> > (File)context.get( "foo:directory" );
>
> Those are not equivalent. 

from a components point of view they are. One is syntactic sugar for the 
other.

> In the former case, context IS-A FooContext.  In
> the latter case, context need only HAVE-A FooContext (perhaps).

I am sure most people here are comfortable with the difference between these 
concepts.

> > So this means code like the following is not really an approved approach.
> > ((FooContext)context).getFooDirectory()
> > ((BarContext)context).getBarDirectory()
>
> I would consider that to be a particularly poor approach, anyway, for the
> above mentioned reasons.

I don't think anyone would consider that a great approach.

-- 
Cheers,

Peter Donald
*------------------------------------------------------*
| "Nearly all men can stand adversity, but if you want |
| to test a man's character, give him power."          |
|       -Abraham Lincoln                               |
*------------------------------------------------------*


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


RE: [PROPOSAL] Context Defined

Posted by "Noel J. Bergman" <no...@devtech.com>.
> Assume that we ignore syntactic sugar and access data via "well defined"
> entrys. So rather than
> ((FooContext)context).getFooDirectory()
> we use
> (File)context.get( "foo:directory" );

Those are not equivalent.  In the former case, context IS-A FooContext.  In
the latter case, context need only HAVE-A FooContext (perhaps).

> So this means code like the following is not really an approved approach.
> ((FooContext)context).getFooDirectory()
> ((BarContext)context).getBarDirectory()

I would consider that to be a particularly poor approach, anyway, for the
above mentioned reasons.

	--- Noel


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PROPOSAL] Context Defined

Posted by Peter Donald <pe...@realityforge.org>.
Lets simplify a bit.

Assume that we ignore syntactic sugar and access data via "well defined" 
entrys. So rather than 

((FooContext)context).getFooDirectory()

we use

(File)context.get( "foo:directory" );

And lets also assume that there are few (if any?) reasonable use cases where 
you would cast a context to multiple different types because domain specific 
services don't tend to cross multiple domains. Last time this was proposed, 
no one was able to come up with a viable use case for this. So this means 
code like the following is not really an approved approach.

((FooContext)context).getFooDirectory()
((BarContext)context).getBarDirectory()

If you make those above assumptions then you have just defined Context as 
defined by Info. See;

http://jakarta.apache.org/avalon/excalibur/info/
http://jakarta.apache.org/avalon/excalibur/info/context.html

-- 
Cheers,

Peter Donald
*------------------------------------------------------*
| An expert is someone who knows everything about the  |
| topic except for its place in the world.             |
*------------------------------------------------------*


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PROPOSAL] Context Defined

Posted by Paul Hammant <Pa...@yahoo.com>.
Stefano

>>> I'm mostly comfortable with the definition you've given.  I commend 
>>> you for attempting a non-partisan solution to this issue. I'd like 
>>> to propose that for this effort *you* are seen to lead the dialogue 
>>> and dissentors to definitions suggest patches to you, rather that 
>>> write some 10 page redifinition.  
>>
>>
>>
>>
>> Umm, I wonder what Paul is talking about ...
>>
>>   dis-sent-er:
>>
>>      One who refuses to accept the doctrines or usages
>>      of an established or a national church, especially
>>      a Protestant who dissents from the Church of England.
>>
>> Seems to me that you can only be a dissenter if you have an 
>> established belief from which one dissent - and if anything the 
>> threads related to context clearly indicate that there is hardly a 
>> case for an established belief pertaining to context.
>>
>> ;-)
>
>
> Paul, Stephen, can we start behaving as adults and dissipate personal 
> friction between ourselves instead of throwing it back into the 
> community? This is for *both* of you.

Actually, I stand by what I said.  By pushing forward Leo as the lead 
for this, indicating his non partisan nature, I am doing the right 
thing.  Both myself and anyone who might have contrary opinion are both 
losers.  You'll note that I did not mention anyone's name in association 
with negative connotations in any email in this thread.  Stefano, you've 
not afforded me the same courtesy...

- Paul


--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PROPOSAL] Context Defined

Posted by Stefano Mazzocchi <st...@apache.org>.
Stephen McConnell wrote:

> What your better of doing is putting together and posting the Cocoon use 
> case for context - what are you doing today - what's wrong with it - 
> what right with it - how do the things we are discussing play into this 
> - i.e. constructive, useful stuff.

Very good point.

-- 
Stefano Mazzocchi                               <st...@apache.org>
--------------------------------------------------------------------



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PROPOSAL] Context Defined

Posted by Stephen McConnell <mc...@apache.org>.

Stefano Mazzocchi wrote:

> Stephen McConnell wrote:
>
>>
>>
>> Paul Hammant wrote:
>>
>>> Leo,
>>>
>>>>
>>>> the Context interface and its associated stage - Contextualizable - 
>>>> has been the subject of much controversy. As a matter of fact, I'd 
>>>> say that it is the single most controversial subject we have in 
>>>> Framework, and I'd like to propose a way where I think the 
>>>> conflicting viewpoints can be accomodated, although this will 
>>>> require some compromise.
>>>>
>>>> -oOo-
>>>>
>>>> [...]
>>>
>>>
>>>
>>>
>>> I'm mostly comfortable with the definition you've given. I commend 
>>> you for attempting a non-partisan solution to this issue. I'd like 
>>> to propose that for this effort *you* are seen to lead the dialogue 
>>> and dissentors to definitions suggest patches to you, rather that 
>>> write some 10 page redifinition. 
>>
>>
>>
>>
>> Umm, I wonder what Paul is talking about ...
>>
>> dis-sent-er:
>>
>> One who refuses to accept the doctrines or usages
>> of an established or a national church, especially
>> a Protestant who dissents from the Church of England.
>>
>> Seems to me that you can only be a dissenter if you have an 
>> established belief from which one dissent - and if anything the 
>> threads related to context clearly indicate that there is hardly a 
>> case for an established belief pertaining to context.
>>
>> ;-)
>
>
> Paul, Stephen, can we start behaving as adults and dissipate personal 
> friction between ourselves instead of throwing it back into the 
> community? This is for *both* of you.
>
> Thank you very much.
>

Stafano:

What are you talking about? I would not Paul's message childish - overly 
cautious perhaps - but my take is that that's only because Paul's been 
burned on this subject once before. My reply ... subtle? Yes. Childish ? 
No. It takes into the account the past, my perception of Paul concers on 
where we move on this subject, and interests in seeing good old 
fashioned colaboration as we move forward on this.

Please, let's drop these derogatory comments - they're not justified or 
helpful.

What your better of doing is putting together and posting the Cocoon use 
case for context - what are you doing today - what's wrong with it - 
what right with it - how do the things we are discussing play into this 
- i.e. constructive, useful stuff.

Cheers, Steve.

-- 

Stephen J. McConnell

OSM SARL
digital products for a global economy
mailto:mcconnell@osm.net
http://www.osm.net




--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PROPOSAL] Context Defined

Posted by Stefano Mazzocchi <st...@apache.org>.
Stephen McConnell wrote:
> 
> 
> Paul Hammant wrote:
> 
>> Leo,
>>
>>>
>>> the Context interface and its associated stage - Contextualizable - 
>>> has been the subject of much controversy. As a matter of fact, I'd 
>>> say that it is the single most controversial subject we have in 
>>> Framework, and I'd like to propose a way where I think the 
>>> conflicting viewpoints can be accomodated, although this will require 
>>> some compromise.
>>>
>>>                               -oOo-
>>>
>>> [...]
>>
>>
>>
>> I'm mostly comfortable with the definition you've given.  I commend 
>> you for attempting a non-partisan solution to this issue. I'd like to 
>> propose that for this effort *you* are seen to lead the dialogue and 
>> dissentors to definitions suggest patches to you, rather that write 
>> some 10 page redifinition.  
> 
> 
> 
> Umm, I wonder what Paul is talking about ...
> 
>   dis-sent-er:
> 
>      One who refuses to accept the doctrines or usages
>      of an established or a national church, especially
>      a Protestant who dissents from the Church of England.
> 
> Seems to me that you can only be a dissenter if you have an established 
> belief from which one dissent - and if anything the threads related to 
> context clearly indicate that there is hardly a case for an established 
> belief pertaining to context.
> 
> ;-)

Paul, Stephen, can we start behaving as adults and dissipate personal 
friction between ourselves instead of throwing it back into the 
community? This is for *both* of you.

Thank you very much.

-- 
Stefano Mazzocchi                               <st...@apache.org>
--------------------------------------------------------------------



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Dissent [was [PROPOSAL] Context Defined]

Posted by Paul Hammant <Pa...@yahoo.com>.
Stephen,

> Umm, I wonder what Paul is talking about ...

I set out with the belief that I would dissent from Leo's line, yet felt 
happy enough that I could trust him to lead us to a common design. I 
found out whilst typing that his design is fairly good already.  I do 
not expect everyone to agree.  I was hoping that that other sould see 
fit to let Leo lead this topic given his non-partisan stance on this 
topic.  I'm hopeful that the thread can evolve on a single direction 
under Leo's lead.

- Paul





--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PROPOSAL] Context Defined

Posted by Stephen McConnell <mc...@apache.org>.

Paul Hammant wrote:

> Leo,
>
>>
>> the Context interface and its associated stage - Contextualizable - 
>> has been the subject of much controversy. As a matter of fact, I'd 
>> say that it is the single most controversial subject we have in 
>> Framework, and I'd like to propose a way where I think the 
>> conflicting viewpoints can be accomodated, although this will require 
>> some compromise.
>>
>>                               -oOo-
>>
>> [...]
>
>
> I'm mostly comfortable with the definition you've given.  I commend 
> you for attempting a non-partisan solution to this issue. I'd like to 
> propose that for this effort *you* are seen to lead the dialogue and 
> dissentors to definitions suggest patches to you, rather that write 
> some 10 page redifinition.  


Umm, I wonder what Paul is talking about ...

   dis-sent-er:

      One who refuses to accept the doctrines or usages
      of an established or a national church, especially
      a Protestant who dissents from the Church of England.

Seems to me that you can only be a dissenter if you have an established 
belief from which one dissent - and if anything the threads related to 
context clearly indicate that there is hardly a case for an established 
belief pertaining to context.

;-)

Cheers, Steve.

<snip/>

-- 

Stephen J. McConnell

OSM SARL
digital products for a global economy
mailto:mcconnell@osm.net
http://www.osm.net




--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>


Re: [PROPOSAL] Context Defined

Posted by Paul Hammant <Pa...@yahoo.com>.
Leo,

>
> the Context interface and its associated stage - Contextualizable - 
> has been the subject of much controversy. As a matter of fact, I'd say 
> that it is the single most controversial subject we have in Framework, 
> and I'd like to propose a way where I think the conflicting viewpoints 
> can be accomodated, although this will require some compromise.
>
>                               -oOo-
>
> [...]

I'm mostly comfortable with the definition you've given.  I commend you 
for attempting a non-partisan solution to this issue. I'd like to 
propose that for this effort *you* are seen to lead the dialogue and 
dissentors to definitions suggest patches to you, rather that write some 
10 page redifinition.  Fingers crossed we all use <snip/> etc as 
appropriate.

> [...]
> As for the actual type of the context instance being given to the 
> component:
>
> Merlin:
> The component specifies a context class C. That class is instantiated 
> with the  constructor taking one Context parameter. This instance is 
> then given to the component. (This was as I understood it from 
> Stephen's emails, I haven't found any code doing this in the assembly 
> or meta packages, so I might be way off here.)
>
> Phoenix:
> A BlockContext implementation is given directly to the component. No 
> way for the component to specify any other class.
>
>
> Note that both containers completely solve the problem so far as to 
> having a way to specify the expected key-value mappings accessible in 
> the Context.

Note, Phoenix's 'things' delivered by BlockContext are not only entries 
in maps.  requestShutdown (for example) is an action rather than a 
lookupable thing.  Usage :

  blockContext.requestShutdown();

It could not be used like so ..

  ((ShutdownHandler) context.get("shutdownhandler")).requestShutdown();

> What is needed is a way to specify what methods should be avilable in 
> addition to a way to specify key-value mappings accessible via the 
> Context.get method. This is needed in order to be able to capture the 
> Phoenix BlockContext interface. With both meta-models, you can specify 
> a requirement for any key K to map to an object of any type V, and 
> using the standardized context keys, you can specify the meaning of 
> the value V. However, neither allows you to require a method called 
> requestShutdown() that requests a shutdown. While Merlin allows you to 
> specify an implementation class, that method can not be used to 
> provide a BlockContext.

I guess, you've just defined what I said above.

> What I intend to add is the following:
>
>  + A way to specify what mehods are required in the context.
>
>  + A restriction on what methods may be required while still remaining 
> 100% Avalon compatible.
>
>
> How to Specify Methods:
>
> The component will declare one class name designating an interface. 
> This can be done like this:
>
>     <context>
>         <require-interface 
> name="org.apache.avalon.phoenix.BlockContext"/>
>     </context>
>
> This indicates that the context object being passed to contextualize() 
> must be cast-able to a BlockContext. This is read as: "The component 
> requires that all methods in the BlockContext interface is present in 
> the context, and that the context object given can be casted to a 
> BlockContext."

Sounds plausible.

> A Restriction on Methods:
>
> There will be a set of standard interfaces in Framework. Any component 
> may request any union of those interfaces. For example, if we have in 
> framework:
>
>     interface WorkDirectoryContext {
>         public File getWorkDirectory ();
>     }
>
>     interface ContextDirectoryContext {
>         public File getContextDirectory ();
>     }

I like the sound of that. It is similar to something I wafted out some 
weeks ago.

> A component may have an interface:
>
>     interface MyContextInterface
>         extends ContextDirectoryContext,
>                 WorkDirectoryContext
>     {};

:-)

>
> And may specify that interface:
>
>     <context>
>         <require-interface name="org.example.MyContextInterface"/>
>     </context>
>
> And can expect to have the request fulfilled in any 100% Avalon 
> container. (Alternatively we can limit interfaces to Avalon Micro 
> Edition, SE, or EE, depending on the profiles we come up with for the 
> übercontainer.)  Note that this does in no way exclude specifying 
> key-value pair requirements. A component can specify key-value pairs, 
> an interface, both or neither.
>
>
> A final restriction on the methods are that the method signatures must 
> be unique. That is, if we in framework have two interfaces:
>
>     interface WorkDirectoryContext {
>         public File getDirectory ();
>     }
>
>     interface ContextDirectoryContext {
>         public File getDirectory ();
>     }
>
> With identical signatures, a union of those interfaces
>
>     interface MyContextInterface
>         extends ContextDirectoryContext,
>                 WorkDirectoryContext
>     {};
>
> will only have one method, and furthermore it is *impossible* to 
> determine through which interface a call was made. That is:
>
>     MyContextInterface mci = ...;
>
>     // These two method calls are indistinguishale.
>     // There is no way, even with dynamic proxies,
>     // for the mci object to know whether the context
>     // directory or the work directory should be returned.
>     ((WorkDirectoryContext) mci).getDirectory ();
>     ((ContextDirectoryContext) mci).getDirectory ();

Agree.

> We can ease that restriction by only requiring method signatures in 
> the interfaces in Framework to be unique, but this would make it 
> harder to promote a method into Framework. Obvious conclusion: these 
> context interfaces should be kept to a minimum.
>
>
> What we allow in Framework:
>
> It is my view that the methods in Framework should be limited to 
> simple data-access methods, such as getWorkDirectory and 
> getContextDirectory, and that methods such as requestShutdown should 
> be left out. The reasoning behind this is as follows:
>
>  + There is major controversy regarding the exposure of services, such 
> as requestShutdown (in particular that one).
>
>  + Few components in Phoenix uses that method.

That is not true. Real world companies who's codebases you have no 
visibilit of use that feature.

>  + In fact, I think most Phoenix blocks only use the 
> getContextDirectory method.

Your visibility again.

>  + Therefore, we can lower the requirements on those blocks, thus 
> making them portable.
>
>  + For the few blocks that *do* require a requestShutdown or similar, 
> they can declare a requirement of BlockContext.

If is is to be the case that some interfaces ( a core set) are inside 
A-F, then fine, it already liked that adea.  If we understand that 
people will make specialised containers that build on A-F concepts and 
they can have their own Context derivatives, then that is fine too.

>  + Those few blocks will remain non-portable, but I guess they are so 
> few that it doesn't matter.
>
> Also, it is my opinion that:
>
>  + Addition of a context interface to Framework should be via 
> consensus vote.
>
>  + Domain-specific contexts, such as EJB contexts and servlet 
> contexts, should not be allowed into Framework, as neither EJBs nor 
> Servlets are Avalon components. 

Agree.

>                              -oOo-
>
>
> PROVIDING A CONTEXT
> -------------------
>
> In the previos section I established that a component may place two 
> types of requirements on a context:
>
>  1) Key-value mappings.
>
>  2) Methods in the context interface.
>
> How to provide (1) is a solved problem and there is concensus on it.
>
> As for (2), I expect the container to have some class that implements 
> Context:
>
>     class ContextImpl implements Context { ... }
>
> That class should implement *all* Framework-level interfaces:
>
>     class ContextImpl implements Context,
>         WorkDirectoryContext, ContextDirectoryContext { ... }

... in what ever way the container sees fit.  Non need to use A-F 
default impls as long as the interfaces are honored.

> [..]

>                              -oOo-
>
> Summary:
>
> I have shown a way to declare a context requirement for components 
> that captures all current usage patterns, and shown how the 
> requirement can be satisfied by a container. The methods shown here 
> can be used to define ServletContexts, EJB contexts, etc. as well. In 
> particular, they can be used to define the Phoenix BlockContext and 
> the JAMES MailContext. Portability suffers a little, but not enough to 
> make it an issue. 

Sounds good. We must not forget that the MailetContext is ficticious 
though (respect for the JAMES team).



--
To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
For additional commands, e-mail: <ma...@jakarta.apache.org>