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/03/03 22:52:20 UTC

[Proposal] ECM / ECS / AbstractContainer

All,

there is a lot of code duplicated between the ExcaliburComponentManager and
the
ExcaliburComponentSelector. Basically, they both implement Contextualizable,
Composable (ECM only), RoleManageable and LogKitManageable. These interfaces
are just implemented in order to pass on the context etc. to the
ComponentHandlers.

The code for this is also very useful for any other
Component-that-has-subComponents.

My example is this:

I have a component that will use the strategy pattern. That is, it has a
method
that is something like this:

  public Action whatToDoNext (Context context);

So, given something, it will return an action for the context. Now comes
the fun part: It solves this by having another component within itself
that it passes the context on to and recieves an Action in return.

*That* component may in turn have sub-components.

So, I end up with a decision tree where the nodes are components.

For example, suppose we want to do A in the afternoon and B otherwise, with
the exception that instead of B, we should do C on Sundays.

                      Sunday +--------------- C
                             |
            AM +-------- DayOfWeek ---------- B
               |                     Otherw.
Root ---- TimeOfDay
               |
            PM +--------- A


Each node in the tree would be a component, that could possibly have
subcomponents.

The configuration would look like this:

<tree-root>
  <rule class="TimeOfDay">
      <when start="0" end="12">
          <rule class="DayOfWeek">
              <when start="Monday" end="Saturday">
                  <action class="B"/>
              </when>
              <when start="Sunday" end="Sunday">
                  <action class="C"/>
              </when>
          </rule>
      </when>
      <when start="12" end="24">
          <action class="A"/>
      </when>
  </rule>
</tree-root>

In Cocoon this is solved by looking up the matchers (equivalent to the
DayOfWeek and
TimeOfDay classes in the example) via a ComponentSelector, and passing a
pattern
to them. This is suboptimal when each component instance in the selector
is only used in one place and I would end up with the following instances in
the Selector:

<rule hint="root" class="TimeOfDay">
  <when start="0" end="12" then="day-of-week"/>
  <when start="12" end="24" then="A"/>
</rule>
<rule hint="day-of-week" class="DayOfWeek">
  <when start="Monday" end="Saturday" then="B"/>
  <when start="Sunday" end="Sunday" then="C"/>
</rule>
<rule hint="A" class="FireA"/>
<rule hint="B" class="FireB"/>
<rule hint="C" class="FireC"/>

Of course, if we want to select between weekdays in another part of the
tree - say, do D instead of A on Saturdays, we get an additional:

<rule hint="day-of-week-saturday" class="DayOfWeek">
  <when start="Sunday" end="Friday" then="A"/>
  <when start="Saturday" end="Saturday" then="D"/>
</rule>

(And don't forget to update the hint="root" rule to reference this new
rule!)

And so on. As the tree gets flattened, maintainability is lost, and I would
like
to solve this by allowing each component to have sub-components, just like a
ComponentSelector can select among several sub-Selectors.

This would also allow for powerful rule-based ComponentSelectors to do
N-dimensional
lookups, where the rules need not be coded into the ComponentSelector.

THE PROPOSAL:

Attached is an implementation of AbstractContainer and
ExcaliburComponentManager,
modified to inherit from AbstractContainer.

The AbstractContainer class gathers all the references necessary to create
ComponentHandlers - it does nothing more. What happens with the handlers
is up to the subclass.

I propose that this replace the current implementation of ECM, that the ECS
is rewritten to derive from AbstractContainer, and that AbstractContainer
is make part of Excalibur.

I am not calling a vote just yet.

I am also looking for input regarding:

 - What is the opinion regarding components-that-have-components in Avalon?
   Is this a no-no, with the exception of ComponentSelector?

/LS

Re: [Proposal] ECM / ECS / AbstractContainer

Posted by Berin Loritsch <bl...@apache.org>.
Leo Sutic wrote:
> All,
> 
> there is a lot of code duplicated between the ExcaliburComponentManager and
> the
> ExcaliburComponentSelector. Basically, they both implement Contextualizable,
> Composable (ECM only), RoleManageable and LogKitManageable. These interfaces
> are just implemented in order to pass on the context etc. to the
> ComponentHandlers.

First, I am in the process of separating out the Container and
ComponentManager/Selector interfaces.  This also allows the ability to
use the new ServiceManager interfaces instead of the ComponentManager
interfaces.

Second, what you are proposing is not out of the question.  There are
different ways that it can be accomplished though.

BTW, I don't like the Rolemanageable/LogKitManageable interfaces, and
prefer to pass references via the Context.



> The code for this is also very useful for any other
> Component-that-has-subComponents.

And don't forget Containers that have Containers!



> My example is this:
> 
> I have a component that will use the strategy pattern. That is, it has a
> method
> that is something like this:
> 
>   public Action whatToDoNext (Context context);
> 
> So, given something, it will return an action for the context. Now comes
> the fun part: It solves this by having another component within itself
> that it passes the context on to and recieves an Action in return.
> 
> *That* component may in turn have sub-components.

However, you are referring to a situation where you have a very small
number of components.  If your heirarchical component structure directly
used the handler classes, you should be good to go.

> 
> So, I end up with a decision tree where the nodes are components.
> 
> For example, suppose we want to do A in the afternoon and B otherwise, with
> the exception that instead of B, we should do C on Sundays.
> 
>                       Sunday +--------------- C
>                              |
>             AM +-------- DayOfWeek ---------- B
>                |                     Otherw.
> Root ---- TimeOfDay
>                |
>             PM +--------- A
> 
> 
> Each node in the tree would be a component, that could possibly have
> subcomponents.

In this situation, you have to wonder if you need full components, or
simple decision objects.  But that is neither here nor there.
Basically, the Root decision object/component has one component, and
one answer has another decision component.

> 
> The configuration would look like this:
> 
> <tree-root>
>   <rule class="TimeOfDay">
>       <when start="0" end="12">
>           <rule class="DayOfWeek">
>               <when start="Monday" end="Saturday">
>                   <action class="B"/>
>               </when>
>               <when start="Sunday" end="Sunday">
>                   <action class="C"/>
>               </when>
>           </rule>
>       </when>
>       <when start="12" end="24">
>           <action class="A"/>
>       </when>
>   </rule>
> </tree-root>

All you need to do in each of these cases is use them like the
interpreted sitemap in Cocoon.

You're root component can recursively use the decision method
(lighter than a whole component) to get down to the final
decision.  The method would look something like this:

Action getAction(Context c, Configuration rules)
{
     if ( !rules.getName().equals("rule") )
     {
         throw new IllegalStateException( "No rules specified" );
     }

     Rule = (Rule) m_ruleSelector.select(rules.getAttribute("class"));

     Configuration[] when = rules.getChildren("when");

     for (int i = 0; i < when.length; i++)
     {
         if ( rule.inRange( c,
                            when[i].getAttribute("start"),
                            when[i].getAttribute("end") ) )
         {
             Configuration result = when[i].getChild();
             if (result.getName().equals("rule"))
             {
                 return getAction( c, result );
             }
             else
             {
                 return (Action) m_actionSelector.select(
                             result.getAttribute( "class" ) );
             }
         }
     }
}

> 
> In Cocoon this is solved by looking up the matchers (equivalent to the
> DayOfWeek and
> TimeOfDay classes in the example) via a ComponentSelector, and passing a
> pattern
> to them. This is suboptimal when each component instance in the selector
> is only used in one place and I would end up with the following instances in
> the Selector:
> 
> <rule hint="root" class="TimeOfDay">
>   <when start="0" end="12" then="day-of-week"/>
>   <when start="12" end="24" then="A"/>
> </rule>
> <rule hint="day-of-week" class="DayOfWeek">
>   <when start="Monday" end="Saturday" then="B"/>
>   <when start="Sunday" end="Sunday" then="C"/>
> </rule>
> <rule hint="A" class="FireA"/>
> <rule hint="B" class="FireB"/>
> <rule hint="C" class="FireC"/>

You don't have to flatten the configuration, if you interpret it on the
fly.



-- 

"They that give up essential liberty to obtain a little temporary safety
  deserve neither liberty nor safety."
                 - Benjamin Franklin


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


Re: Composition vs Inheritance (RE: ContainerManager (was: RE: [Proposal] ECM / ECS / AbstractContainer))

Posted by Berin Loritsch <bl...@apache.org>.
Leo Simons wrote:
>>>I would like to split this one and break out the get and has methods.
>>>
>>>AbstractContainer: Provides methods for obtaining handlers to
>>>
>>components.
>>
>>>AbstractManager  : Provides methods for accessing component handlers.
>>>
>>>Basically, AbstractContainer.m_mapper would be AbstractManager.m_mapper,
>>>and the rest of the class follows as needed to compile.
>>>
> 
> not commenting on the rest, here's a question: is this really a
> place where inheritance/abstract classes is smart? (me, I always
> use composition by default and switch to inheritance when it is
> neccessary. A maintainability issue...)
> 
> Actually, I've been wondering whether this should be at least
> mentioned in the framework documentation.
> 
> I generally prefer:
> 
> 
> interface SomeInterface
> interface SomeInterfaceHelper
> 
> class DefaultSomeInterfaceHelper implements SomeInterfaceHelper
> class DefaultSomeInterface implements SomeInterface
> class Alternate1SomeInterface implements SomeInterface
> class Alternate2SomeInterface implements SomeInterface
> 
> DefaultSomeInterface --uses--> DefaultSomeInterfaceHelper
> Alternate1SomeInterface --uses--> DefaultSomeInterfaceHelper
> Alternate2SomeInterface --uses--> DefaultSomeInterfaceHelper
> 
> 
> to:
> 
> 
> interface SomeInterface
> 
> abstract class AbstractSomeInterface implements SomeInterface
> 
> class DefaultSomeInterface extends AbstractsomeInterface
> class Alternate1SomeInterface extends AbstractsomeInterface
> class Alternate2SomeInterface extends AbstractsomeInterface
> 
> 
> while the first one generally means more code, it improves
> code readability. For the most part, Framework and Excalibur
> follow this approach. Pete's been known to do it differently
> in places =)
> 
> thoughts?


The ContainerManager and Container handle two different concerns.
The ContainerManager's responsibility is to manage the Container
instance, and all the other helper managers in the system.  It is
also meant to reuse existing Managers if they are already created.
The Container is designed to manage the Component instances.  The
AbstractContainer does make use of other managers and components
to do its job.  But it's purpose is to map components between the
different component instances.  I.e. it can be so fine grained as
to allow some components to be available to one component but not
another.

The concrete example would be the following scenario:

Components:

DataSourceComponent
Store
Monitor

Store may be able to obtain a reference to the DataSourceComponent
and the Monitor, but the DataSourceComponent wouldn't be able to
obtain a reference to anything else.  Furthermore, the Monitor might
be able to reference the DataSourceComponent but not the Store.

In the ECM, everything is accessible to everything else.

The AbstractContainer provides all the basic logic and hooks to allow
you to enforce whatever policy you want and still maintain the same
configuration format.  The AbstractContainer defaults to the same
behavior as the ECM, but allows you to have more fine control.



-- 

"They that give up essential liberty to obtain a little temporary safety
  deserve neither liberty nor safety."
                 - Benjamin Franklin


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


Composition vs Inheritance (RE: ContainerManager (was: RE: [Proposal] ECM / ECS / AbstractContainer))

Posted by Leo Simons <ma...@leosimons.com>.
> > I would like to split this one and break out the get and has methods.
> >
> > AbstractContainer: Provides methods for obtaining handlers to
> components.
> > AbstractManager  : Provides methods for accessing component handlers.
> >
> > Basically, AbstractContainer.m_mapper would be AbstractManager.m_mapper,
> > and the rest of the class follows as needed to compile.

not commenting on the rest, here's a question: is this really a
place where inheritance/abstract classes is smart? (me, I always
use composition by default and switch to inheritance when it is
neccessary. A maintainability issue...)

Actually, I've been wondering whether this should be at least
mentioned in the framework documentation.

I generally prefer:


interface SomeInterface
interface SomeInterfaceHelper

class DefaultSomeInterfaceHelper implements SomeInterfaceHelper
class DefaultSomeInterface implements SomeInterface
class Alternate1SomeInterface implements SomeInterface
class Alternate2SomeInterface implements SomeInterface

DefaultSomeInterface --uses--> DefaultSomeInterfaceHelper
Alternate1SomeInterface --uses--> DefaultSomeInterfaceHelper
Alternate2SomeInterface --uses--> DefaultSomeInterfaceHelper


to:


interface SomeInterface

abstract class AbstractSomeInterface implements SomeInterface

class DefaultSomeInterface extends AbstractsomeInterface
class Alternate1SomeInterface extends AbstractsomeInterface
class Alternate2SomeInterface extends AbstractsomeInterface


while the first one generally means more code, it improves
code readability. For the most part, Framework and Excalibur
follow this approach. Pete's been known to do it differently
in places =)

thoughts?

- Leo


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


Re: ContainerManager (was: RE: [Proposal] ECM / ECS / AbstractContainer)

Posted by Berin Loritsch <bl...@apache.org>.
Leo Sutic wrote:
> 
>>From: Berin Loritsch [mailto:bloritsch@apache.org]
>>
>>Leo Sutic wrote:
>>
>>>And I now have a completely initialized component manager
>>>inside the containerManager. Then I do a:
>>>
>>>    ComponentManager myManager =
>>>        (ComponentManager) containerManager.getContainer ();
>>>
>>I want to move this part to a ContextManager, so that it makes it easier
>>to reuse instances of PoolManager et. al. from a parent container.
>>
>>
>>>and when I want to process a request, I can look up the Processor
>>>(for example) component in myManager and pass it the required
>>>
>>parameters.
>>
>>The way I would envision it for something like Cocoon where the Cocoon
>>object *IS* a processor, I would do this in the servlet code:
>>
>>Processor cocoon = (Processor) containerManager.getContainer();
>>
>>I would not expose the ComponentManager to the outside world (Subversion
>>of Control you know).
>>
>>
>>>And now, I want to write a component that holds several other
>>>
>>components.
>>
>>>I take it then, that this would be done just as above. The component
>>>would have a CM created via the ContainerManager.
>>>
>>THere is an AbstractContainer class that takes care of the default
>>implementation of this.  It builds all the component handlers and such
>>for the Container.  The COntainerManager merely manages the instance
>>of the Container.  It has its ComponentManager to help resolve config
>>files.
>>
> 
> I would like to split this one and break out the get and has methods.
> 
> AbstractContainer: Provides methods for obtaining handlers to components.
> AbstractManager  : Provides methods for accessing component handlers.
> 
> Basically, AbstractContainer.m_mapper would be AbstractManager.m_mapper,
> and the rest of the class follows as needed to compile.
> 
> 
>>>Questions:
>>>
>>>1) How do I pass a parent CM to the new CM that I create via the
>>>ContainerManager?
>>>
>>:)  I am working on that.  Basically, if I pass it in the constructor,
>>or the ContextManager, I can handle that quite easily.
>>
> 
> Or pass it in if the created container implements Composable as the
> container
> is being put through the lifecycle steps. The container would
> get the parent cm in compose. The parent cm is passed to the
> ContainerManager via the Context (see below).
> 
> I think the ContainerManager must allow for more overrides - one should, as
> with the configuration below, always be able to pass in a pre-generated
> CM, or Context, or Configuration.
> 
> 
>>>2) How do I pass a non-file Configuration to the ContainerManager?
>>>
> (Useful
> 
>>>in the second case.)
>>>
>>Good question.  My thoughts are to make the ContainerManager use the
>>ContextManager.
>>
> 
>>It would retrieve the URI from the context and retrieve
>>a Configuration, and store the configuration in the Context.  Next, it
>>would pull that configuration and generate the resource.
>>
> 
> Or:
> 
> public class ContextManager {
> 
>   ...
> 
>   public void buildConfigurationFromFile (String path) {
>     ...
>     // Build the configuration from the path, resolving it relative to the
>     // context base URI and so on.
>     ...
>     setConfiguration (newlyBuiltConfiguration);
>   }
> 
>   public void setConfiguration (Configuration configuration) {
>     // put the configuration into the context
>     ...
>   }
> 
>   ...
> 
> }
> 
> and replace the constructors of ContainerManager with:
> 
>   public ContainerManager( final Context initParams,
>                            final Logger primordialLogger )
> 
> The ContainerManager will then use the objects in the initParams to
> initialize the container. That is, initParams contains a configuration,
> it contains Parameters, a ComponentManager and so on. It also
> contains a Context that will be passed on to the created container.
> 
> That Context needs some post-processing, since the created container must
> be able to use the Context it recieved in contextualize to create its
> own sub-container.
> 
> Therefore, the Context actually passed on to the container is
> 
>   Context as given in the initParams parameter to the
>            ContainerManager constructor
>                           +
>           some elements of initParams itself.
> 
> The parts of initParams that should be passed on to the container are
> basically those that the container can not guess itself, but that
> are needed to create a sub-container:
> 
> CONTEXT_DIRECTORY
> WORK_DIRECTORY
> LOGKIT_CONFIG
> THREADS_CPU
> THREAD_TIMEOUT
> 
> 
>>>4) Is it your intention to not use the Lifestyle interfaces ThreadSafe
>>>
> etc.
> 
>>>   any more and replace them with handler attributes in the
>>>
> configuration file?
> 
>>YES!  Absolutely.  I want to remove the dependancies on marker
>>interfaces in general.
>>
> 
> I think marker interfaces are great: You will need to document the type
> of handler a component uses anyway, so why not make it part of the component
> class? C#, for example, allows attributes to be set for every object in the
> system. Java has interfaces. It would be unwise to throw it away.
> 
> I'd go for a handler="..." override and an autodetect based on marker
> interfaces.
> 
> No big deal - the ContainerManager is such an improvement that this is
> trivial.
> 
> 
>>>>Nothing stops you from directly using the ComponentHandler classes.  I
>>>>would suggest you make all of them ThreadSafe, so you don't have any
>>>>funny logic and make things easy on yourself....
>>>>
>>>>
>>>That's pretty much my conclusion, too.
>>>
>>>But for future work I will need the ContainerManager or something
>>>exactly like that.
>>>
>>:)
>>
>>I'm working as fast as I can, but if you want to help, I would
>>appreciate it.
>>
> 
> I'm in.
> 
> /LS
> 
> 
> --
> To unsubscribe, e-mail:   <ma...@jakarta.apache.org>
> For additional commands, e-mail: <ma...@jakarta.apache.org>
> 
> 



-- 

"They that give up essential liberty to obtain a little temporary safety
  deserve neither liberty nor safety."
                 - Benjamin Franklin


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


Re: ContainerManager (was: RE: [Proposal] ECM / ECS / AbstractContainer)

Posted by Berin Loritsch <bl...@apache.org>.
Leo Sutic wrote:
> 
>>From: Berin Loritsch [mailto:bloritsch@apache.org]
>>
>>Leo Sutic wrote:
>>
>>>I would like to split this one and break out the get and has methods.
>>>
>>>AbstractContainer: Provides methods for obtaining handlers to
>>>
>>components.
>>
>>>AbstractManager  : Provides methods for accessing component handlers.
>>>
>>>Basically, AbstractContainer.m_mapper would be AbstractManager.m_mapper,
>>>and the rest of the class follows as needed to compile.
>>>
>>
>>Why?  What does it gain?
>>
> 
> The current AbstractContainer puts all components in a hashmap and accesses
> them through that map. It also contains code to implement ComponentManager
> functions (ContainerComponentManager).
> 
> I'd like to factor out the parts dealing with aquiring the component
> handlers and separate it from the code dealing with how to manage
> those handlers once aquired.
> 
> As it is now, AbstractContainer has a lot of good, useful code, but it comes
> with too many strings attached. While it is possible to subclass it and
> override methods to get any behavior, the contract between AbstractContainer
> and its subclasses is a bit too big for me to be able to get "any behavior"
> via subclassing.

Ok.  I would like to see your proposal.



>>>That Context needs some post-processing, since the created
>>>
>>container must
>>
>>>be able to use the Context it recieved in contextualize to create its
>>>own sub-container.
>>>
>>>Therefore, the Context actually passed on to the container is
>>>
>>>  Context as given in the initParams parameter to the
>>>           ContainerManager constructor
>>>                          +
>>>          some elements of initParams itself.
>>>
>>>The parts of initParams that should be passed on to the container are
>>>basically those that the container can not guess itself, but that
>>>are needed to create a sub-container:
>>>
>>>CONTEXT_DIRECTORY
>>>WORK_DIRECTORY
>>>LOGKIT_CONFIG
>>>THREADS_CPU
>>>THREAD_TIMEOUT
>>>
>>There are defaults for these values--but they are meant to be overriden.
>>
> 
> What I want to achieve is that global settings should propagate down the
> hierarchy of containers. So if you set THREAD_TIMEOUT to 15000 for the
> root container, that should propagate to any child container.

That is exactly what I am working on.  When a Container is given its
context, it will be able to use that same context as the parent context
for the child container.  Basically, the hierarchy would go like this:

m_childContainerManager = new ContainerManager( m_context );
ContextManager cmanager = m_childContainerManager.getContextManager();
cmanager.setClassName( "org.apache.cocoon.sitemap.InterpretedSitemap" );
cmanager.setContextDirectory( new File(
      (File) m_context.get( Context.CONTEXT_DIRECTORY ),
      "mount/location/" )
);

m_childContainerManager.initialize();

As you see, you only need to override certain values.  The rest are
obtained from the parent context.  I am working in a fresh class to
provide this functionality (DefaultContainerManager).



>>If a container has child containers, it would have a ContainerManaager
>>for each child, and override the CONTEXT_DIRECTORY for each one.
>>
> 
> Yes, and probably set it to CONTEXT_DIRECTORY (as given in its own context)
> +
> childContainerName. So CONTEXT_DIRECTORY must be available to the container.

Of course.

>>>>YES!  Absolutely.  I want to remove the dependancies on marker
>>>>interfaces in general.
>>>>
>>>>
>>>I think marker interfaces are great
>>>
>>The problem is when you have a deep implementation or interface
>>hierarchy.  If any superclass implements one lifestyle interface, then
>>you cannot change it down the line.
>>
> 
> You'd have an ordering ThreadSafe < PerThread < Poolable < SingleThreaded,
> but yeah, I can see that we're trying to be a little too smart here.

Not to mention that it is quite awkward when some of those classes are
in framework, some are in Excalibur, but they are not all in one
package.  Furthermore, this way we don't have to change the library if
we find a new way to manage component instances (like I did with the
Per-Thread policy).



>>>I'm in.
>>>
>>Excellent!  I can send you the current rework progress (that has come to
>>a standstill due to some fires I have to put out at work) off line,
>>maybe you can flesh it out and get it committed.
>>
> 
> Bring it on.
> 
> I'll have to start off by figuring out just what your intentions are for
> the different classes, so we don't get some skewed evolution.

It's in CVS now.  I didn't mean to commit it, but once I did, I figured
we might as well work on it there.  The DefaultContainerManager is where
the new stuff will be--but it isn't functioning yet.



>>BTW, ContainerManager crushes ExcaliburComponentManager in scalability.
>>Part of this is due to asynchronous management
>>
> 
> Like the InitComponentHandlerCommand? I searched but couldn't find where
> it was used. Maybe I have an older version.

:) Yes.  The InitComponentHandlerCommand is (or supposed is to be)
issued to the Command Queue.  The queue is attached to the
CommandManager which in turn executes the command.


-- 

"They that give up essential liberty to obtain a little temporary safety
  deserve neither liberty nor safety."
                 - Benjamin Franklin


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


RE: ContainerManager (was: RE: [Proposal] ECM / ECS / AbstractContainer)

Posted by Leo Sutic <le...@inspireinfrastructure.com>.

> From: Berin Loritsch [mailto:bloritsch@apache.org]
>
> Leo Sutic wrote:
> >
> > I would like to split this one and break out the get and has methods.
> >
> > AbstractContainer: Provides methods for obtaining handlers to
> components.
> > AbstractManager  : Provides methods for accessing component handlers.
> >
> > Basically, AbstractContainer.m_mapper would be AbstractManager.m_mapper,
> > and the rest of the class follows as needed to compile.
>
>
> Why?  What does it gain?

The current AbstractContainer puts all components in a hashmap and accesses
them through that map. It also contains code to implement ComponentManager
functions (ContainerComponentManager).

I'd like to factor out the parts dealing with aquiring the component
handlers and separate it from the code dealing with how to manage
those handlers once aquired.

As it is now, AbstractContainer has a lot of good, useful code, but it comes
with too many strings attached. While it is possible to subclass it and
override methods to get any behavior, the contract between AbstractContainer
and its subclasses is a bit too big for me to be able to get "any behavior"
via subclassing.

> I was actually in the process of performing this change.  Basically
> allowing for the exchanging of ContainerManager implementations--that
> are specific to a certain platform.  You can override methods to
> remove the need for reflection--although the default implementation
> is available.
>
> Also, the ContainerManager is being split into interface and
> implementation....

Cool.

> > That Context needs some post-processing, since the created
> container must
> > be able to use the Context it recieved in contextualize to create its
> > own sub-container.
> >
> > Therefore, the Context actually passed on to the container is
> >
> >   Context as given in the initParams parameter to the
> >            ContainerManager constructor
> >                           +
> >           some elements of initParams itself.
> >
> > The parts of initParams that should be passed on to the container are
> > basically those that the container can not guess itself, but that
> > are needed to create a sub-container:
> >
> > CONTEXT_DIRECTORY
> > WORK_DIRECTORY
> > LOGKIT_CONFIG
> > THREADS_CPU
> > THREAD_TIMEOUT
>
> There are defaults for these values--but they are meant to be overriden.

What I want to achieve is that global settings should propagate down the
hierarchy of containers. So if you set THREAD_TIMEOUT to 15000 for the
root container, that should propagate to any child container.

> If a container has child containers, it would have a ContainerManaager
> for each child, and override the CONTEXT_DIRECTORY for each one.

Yes, and probably set it to CONTEXT_DIRECTORY (as given in its own context)
+
childContainerName. So CONTEXT_DIRECTORY must be available to the container.

> >>YES!  Absolutely.  I want to remove the dependancies on marker
> >>interfaces in general.
> >>
> >
> > I think marker interfaces are great
>
> The problem is when you have a deep implementation or interface
> hierarchy.  If any superclass implements one lifestyle interface, then
> you cannot change it down the line.

You'd have an ordering ThreadSafe < PerThread < Poolable < SingleThreaded,
but yeah, I can see that we're trying to be a little too smart here.

> > I'm in.
>
> Excellent!  I can send you the current rework progress (that has come to
> a standstill due to some fires I have to put out at work) off line,
> maybe you can flesh it out and get it committed.

Bring it on.

I'll have to start off by figuring out just what your intentions are for
the different classes, so we don't get some skewed evolution.

> BTW, ContainerManager crushes ExcaliburComponentManager in scalability.
> Part of this is due to asynchronous management

Like the InitComponentHandlerCommand? I searched but couldn't find where
it was used. Maybe I have an older version.

/LS


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


Re: ContainerManager (was: RE: [Proposal] ECM / ECS / AbstractContainer)

Posted by Berin Loritsch <bl...@apache.org>.
Sorry for the noise earlier, I meant to print, and I hit reply/send ?!?

Leo Sutic wrote:
> 
>>From: Berin Loritsch [mailto:bloritsch@apache.org]
>>
>>Leo Sutic wrote:
>>

>>>I take it then, that this would be done just as above. The component
>>>would have a CM created via the ContainerManager.
>>>
>>THere is an AbstractContainer class that takes care of the default
>>implementation of this.  It builds all the component handlers and such
>>for the Container.  The COntainerManager merely manages the instance
>>of the Container.  It has its ComponentManager to help resolve config
>>files.
>>
> 
> I would like to split this one and break out the get and has methods.
> 
> AbstractContainer: Provides methods for obtaining handlers to components.
> AbstractManager  : Provides methods for accessing component handlers.
> 
> Basically, AbstractContainer.m_mapper would be AbstractManager.m_mapper,
> and the rest of the class follows as needed to compile.


Why?  What does it gain?




>>>Questions:
>>>
>>>1) How do I pass a parent CM to the new CM that I create via the
>>>ContainerManager?
>>>
>>:)  I am working on that.  Basically, if I pass it in the constructor,
>>or the ContextManager, I can handle that quite easily.
>>
> 
> Or pass it in if the created container implements Composable as the
> container
> is being put through the lifecycle steps. The container would
> get the parent cm in compose. The parent cm is passed to the
> ContainerManager via the Context (see below).
> 
> I think the ContainerManager must allow for more overrides - one should, as
> with the configuration below, always be able to pass in a pre-generated
> CM, or Context, or Configuration.

Yep.  see below.

> 
> 
>>>2) How do I pass a non-file Configuration to the ContainerManager?
>>>
> (Useful
> 
>>>in the second case.)
>>>
>>Good question.  My thoughts are to make the ContainerManager use the
>>ContextManager.
>>
> 
>>It would retrieve the URI from the context and retrieve
>>a Configuration, and store the configuration in the Context.  Next, it
>>would pull that configuration and generate the resource.
>>
> 
> Or:
> 
> public class ContextManager {
> 
>   ...
> 
>   public void buildConfigurationFromFile (String path) {
>     ...
>     // Build the configuration from the path, resolving it relative to the
>     // context base URI and so on.
>     ...
>     setConfiguration (newlyBuiltConfiguration);
>   }
> 
>   public void setConfiguration (Configuration configuration) {
>     // put the configuration into the context
>     ...
>   }
> 
>   ...
> 
> }
> 
> and replace the constructors of ContainerManager with:
> 
>   public ContainerManager( final Context initParams,
>                            final Logger primordialLogger )

I was actually in the process of performing this change.  Basically
allowing for the exchanging of ContainerManager implementations--that
are specific to a certain platform.  You can override methods to
remove the need for reflection--although the default implementation
is available.

Also, the ContainerManager is being split into interface and
implementation....

> The ContainerManager will then use the objects in the initParams to
> initialize the container. That is, initParams contains a configuration,
> it contains Parameters, a ComponentManager and so on. It also
> contains a Context that will be passed on to the created container.

:)  In essence yes, that is what is happening.



> That Context needs some post-processing, since the created container must
> be able to use the Context it recieved in contextualize to create its
> own sub-container.
> 
> Therefore, the Context actually passed on to the container is
> 
>   Context as given in the initParams parameter to the
>            ContainerManager constructor
>                           +
>           some elements of initParams itself.
> 
> The parts of initParams that should be passed on to the container are
> basically those that the container can not guess itself, but that
> are needed to create a sub-container:
> 
> CONTEXT_DIRECTORY
> WORK_DIRECTORY
> LOGKIT_CONFIG
> THREADS_CPU
> THREAD_TIMEOUT

There are defaults for these values--but they are meant to be overriden.

I.e. THREADS_CPU defaults to 2, THREAD_TIMEOUT defaults to 15 seconds,
LOGKIT_CONFIG defaults to "context://logkit.xconf", work directory
defaults to "/tmp", and context directory defaults to "./".

If a container has child containers, it would have a ContainerManaager
for each child, and override the CONTEXT_DIRECTORY for each one.



>>>4) Is it your intention to not use the Lifestyle interfaces ThreadSafe
>>>
> etc.
> 
>>>   any more and replace them with handler attributes in the
>>>
> configuration file?
> 
>>YES!  Absolutely.  I want to remove the dependancies on marker
>>interfaces in general.
>>
> 
> I think marker interfaces are great: You will need to document the type
> of handler a component uses anyway, so why not make it part of the component
> class? C#, for example, allows attributes to be set for every object in the
> system. Java has interfaces. It would be unwise to throw it away.
> 
> I'd go for a handler="..." override and an autodetect based on marker
> interfaces.
> 
> No big deal - the ContainerManager is such an improvement that this is
> trivial.

The problem is when you have a deep implementation or interface
hierarchy.  If any superclass implements one lifestyle interface, then
you cannot change it down the line.

Given a situation where you have an interface that is threadsafe
according to its signature (i.e. only one method, or a stateless
component), we might have in implementation that is declared ThreadSafe.
Someone else might come along and extend it, but the new implementation
must be PerThread or Poolable at the least.

You cannot safely change it.  Therefore by declaring it in the "handler"
attribute, you don't loose that very important information in the
inheritance hierarchy.  In the end, this approach is more predictable,
and scales better in large projects.



>>>>Nothing stops you from directly using the ComponentHandler classes.  I
>>>>would suggest you make all of them ThreadSafe, so you don't have any
>>>>funny logic and make things easy on yourself....
>>>>
>>>>
>>>That's pretty much my conclusion, too.
>>>
>>>But for future work I will need the ContainerManager or something
>>>exactly like that.
>>>
>>:)
>>
>>I'm working as fast as I can, but if you want to help, I would
>>appreciate it.
>>
> 
> I'm in.

Excellent!  I can send you the current rework progress (that has come to
a standstill due to some fires I have to put out at work) off line,
maybe you can flesh it out and get it committed.


BTW, ContainerManager crushes ExcaliburComponentManager in scalability.
Part of this is due to asynchronous management, and part of this has
to do with special attention given to reduce thread contention in the
critical path.  ECM brought us a long way, but ContainerManager will
bring us to the next level of ease of use and scalability.



-- 

"They that give up essential liberty to obtain a little temporary safety
  deserve neither liberty nor safety."
                 - Benjamin Franklin


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


ContainerManager (was: RE: [Proposal] ECM / ECS / AbstractContainer)

Posted by Leo Sutic <le...@inspireinfrastructure.com>.

> From: Berin Loritsch [mailto:bloritsch@apache.org]
>
> Leo Sutic wrote:
> >
> > And I now have a completely initialized component manager
> > inside the containerManager. Then I do a:
> >
> >     ComponentManager myManager =
> >         (ComponentManager) containerManager.getContainer ();
>
> I want to move this part to a ContextManager, so that it makes it easier
> to reuse instances of PoolManager et. al. from a parent container.
>
> > and when I want to process a request, I can look up the Processor
> > (for example) component in myManager and pass it the required
> parameters.
>
> The way I would envision it for something like Cocoon where the Cocoon
> object *IS* a processor, I would do this in the servlet code:
>
> Processor cocoon = (Processor) containerManager.getContainer();
>
> I would not expose the ComponentManager to the outside world (Subversion
> of Control you know).
>
> > And now, I want to write a component that holds several other
> components.
> >
> > I take it then, that this would be done just as above. The component
> > would have a CM created via the ContainerManager.
>
> THere is an AbstractContainer class that takes care of the default
> implementation of this.  It builds all the component handlers and such
> for the Container.  The COntainerManager merely manages the instance
> of the Container.  It has its ComponentManager to help resolve config
> files.

I would like to split this one and break out the get and has methods.

AbstractContainer: Provides methods for obtaining handlers to components.
AbstractManager  : Provides methods for accessing component handlers.

Basically, AbstractContainer.m_mapper would be AbstractManager.m_mapper,
and the rest of the class follows as needed to compile.

> > Questions:
> >
> > 1) How do I pass a parent CM to the new CM that I create via the
> > ContainerManager?
>
> :)  I am working on that.  Basically, if I pass it in the constructor,
> or the ContextManager, I can handle that quite easily.

Or pass it in if the created container implements Composable as the
container
is being put through the lifecycle steps. The container would
get the parent cm in compose. The parent cm is passed to the
ContainerManager via the Context (see below).

I think the ContainerManager must allow for more overrides - one should, as
with the configuration below, always be able to pass in a pre-generated
CM, or Context, or Configuration.

> > 2) How do I pass a non-file Configuration to the ContainerManager?
(Useful
> > in the second case.)
>
> Good question.  My thoughts are to make the ContainerManager use the
> ContextManager.

> It would retrieve the URI from the context and retrieve
> a Configuration, and store the configuration in the Context.  Next, it
> would pull that configuration and generate the resource.

Or:

public class ContextManager {

  ...

  public void buildConfigurationFromFile (String path) {
    ...
    // Build the configuration from the path, resolving it relative to the
    // context base URI and so on.
    ...
    setConfiguration (newlyBuiltConfiguration);
  }

  public void setConfiguration (Configuration configuration) {
    // put the configuration into the context
    ...
  }

  ...

}

and replace the constructors of ContainerManager with:

  public ContainerManager( final Context initParams,
                           final Logger primordialLogger )

The ContainerManager will then use the objects in the initParams to
initialize the container. That is, initParams contains a configuration,
it contains Parameters, a ComponentManager and so on. It also
contains a Context that will be passed on to the created container.

That Context needs some post-processing, since the created container must
be able to use the Context it recieved in contextualize to create its
own sub-container.

Therefore, the Context actually passed on to the container is

  Context as given in the initParams parameter to the
           ContainerManager constructor
                          +
          some elements of initParams itself.

The parts of initParams that should be passed on to the container are
basically those that the container can not guess itself, but that
are needed to create a sub-container:

CONTEXT_DIRECTORY
WORK_DIRECTORY
LOGKIT_CONFIG
THREADS_CPU
THREAD_TIMEOUT

> > 4) Is it your intention to not use the Lifestyle interfaces ThreadSafe
etc.
> >    any more and replace them with handler attributes in the
configuration file?
>
> YES!  Absolutely.  I want to remove the dependancies on marker
> interfaces in general.

I think marker interfaces are great: You will need to document the type
of handler a component uses anyway, so why not make it part of the component
class? C#, for example, allows attributes to be set for every object in the
system. Java has interfaces. It would be unwise to throw it away.

I'd go for a handler="..." override and an autodetect based on marker
interfaces.

No big deal - the ContainerManager is such an improvement that this is
trivial.

> >>Nothing stops you from directly using the ComponentHandler classes.  I
> >>would suggest you make all of them ThreadSafe, so you don't have any
> >>funny logic and make things easy on yourself....
> >>
> >
> > That's pretty much my conclusion, too.
> >
> > But for future work I will need the ContainerManager or something
> > exactly like that.
>
> :)
>
> I'm working as fast as I can, but if you want to help, I would
> appreciate it.

I'm in.

/LS


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


Re: [Proposal] ECM / ECS / AbstractContainer

Posted by Berin Loritsch <bl...@apache.org>.
Leo Sutic wrote:
> 
>>From: Berin Loritsch [mailto:bloritsch@apache.org]
>>
>>Leo Sutic wrote:
>>
>>>>From: Leo Simons [mailto:mail@leosimons.com]
>>>>
>>>>Basically, what you are proposing is to create a hierarchy of
>>>>ECMs/ECS rather than a single-level-deep structure, IIUC. The
>>>>advantage of this is that using a tree instead of a map results
>>>>in better maintainability in larger projects. Right?
>>>>
>>>>
>>>That would be one possiblity, and I could make some arguments
>>>for this, but what I want is to factor out the "this component
>>>can have subcomponents" behavior from ECM/ECS. That is the primary goal.
>>>
>>>Both ECM and ECS now have a getComponentHandler method, for example.
>>>Both of them implements LogKitManageable, Contextualizable etc. for
>>>the sole purpose of passing on the obtained LogKitmanager, Context, etc.
>>>to the component handlers.
>>>
>>>What I want to do is create a common superclass for ECM and ECS
>>>and move that code there.
>>>
>>>So to split the questions:
>>>
>>> 1) Should the common code of ECM and ECS be factored out?
>>>    This would make it easier to write ComponentSelectors
>>>    and ComponentManagers.
>>>
>>
>>Yes, but don't call it AbstractContainer.  It will confuse things
>>when the new ContainerManager/Container code is ready for prime
>>time.
>>
> 
> Berin,
> 
> what is your estimate for the ContainerManager/Container code? I
> just found it in excalibur.system (had been looking in
> excalilbur.container before), and if I'd much rather we got that
> stuff going than waste my time with ECM/ECS.
> 
> Just a quick check that I understand the code correctly (it is beautiful,
> BTW):
> 
> If I write a servlet, I'd first grab some parameters from
> some file (like, number of threads per CPU, etc...). Since
> I want to use the MyComponentManager class, I set CONTAINER_CLASS
> to "MyComponentManager", which is a FQCN. Then I do:
> 
>     ContainerManager containerManager = new ContainerManager (parameters);
> 
> And I now have a completely initialized component manager
> inside the containerManager. Then I do a:
> 
>     ComponentManager myManager =
>         (ComponentManager) containerManager.getContainer ();

I want to move this part to a ContextManager, so that it makes it easier
to reuse instances of PoolManager et. al. from a parent container.



> and when I want to process a request, I can look up the Processor
> (for example) component in myManager and pass it the required parameters.

The way I would envision it for something like Cocoon where the Cocoon
object *IS* a processor, I would do this in the servlet code:

Processor cocoon = (Processor) containerManager.getContainer();

I would not expose the ComponentManager to the outside world (Subversion
of Control you know).



> And now, I want to write a component that holds several other components.
> 
> I take it then, that this would be done just as above. The component
> would have a CM created via the ContainerManager.

THere is an AbstractContainer class that takes care of the default
implementation of this.  It builds all the component handlers and such
for the Container.  The COntainerManager merely manages the instance
of the Container.  It has its ComponentManager to help resolve config
files.



> Questions:
> 
> 1) How do I pass a parent CM to the new CM that I create via the
> ContainerManager?

:)  I am working on that.  Basically, if I pass it in the constructor,
or the ContextManager, I can handle that quite easily.

> 2) How do I pass a non-file Configuration to the ContainerManager? (Useful
> in
>    the second case.)

Good question.  My thoughts are to make the ContainerManager use the
ContextManager.  It would retrieve the URI from the context and retrieve
a Configuration, and store the configuration in the Context.  Next, it
would pull that configuration and generate the resource.

That way, if you short-circuit the normal path, directly providing the
Configuration object, it can pick up from there.

> 3) Will the Container interface be a marker interface? (See question 7).

NO!  It is not required, but it is available to easily manage the
contents of the Context object.

> 4) Is it your intention to not use the Lifestyle interfaces ThreadSafe etc.
> any more
>    and replace them with handler attributes in the configuration file?

YES!  Absolutely.  I want to remove the dependancies on marker
interfaces in general.

> 5) CONTAINER_CLASS isa component?

Not necessarily--but it can be.

> 6) CONTAINER_CLASS isa Container? Always / must be?

Again, not necessarily, but it can be.  Since we are trying to move away
from requiring marker interfaces in general, I do not want to enforce
this restriction.  The only requirement is that the Container is extends
Object (the default).

> 7) Will a component that implements Container be treated in a special way by
> the
>    Container that contains it? (See question 3).

No.  A Container is a Container is a Container.  If you implement
lifecycle interfaces, you have them applied.  If not, then nothing
special happens.  It is preferred for the Container to at least
implement Contextualizable so that it can get a reference to all the
helpful managers passed in.



>>Nothing stops you from directly using the ComponentHandler classes.  I
>>would suggest you make all of them ThreadSafe, so you don't have any
>>funny logic and make things easy on yourself....
>>
> 
> That's pretty much my conclusion, too.
> 
> But for future work I will need the ContainerManager or something
> exactly like that.

:)

I'm working as fast as I can, but if you want to help, I would
appreciate it.


-- 

"They that give up essential liberty to obtain a little temporary safety
  deserve neither liberty nor safety."
                 - Benjamin Franklin


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


RE: [Proposal] ECM / ECS / AbstractContainer

Posted by Leo Sutic <le...@inspireinfrastructure.com>.

> From: Berin Loritsch [mailto:bloritsch@apache.org]
>
> Leo Sutic wrote:
> >
> >>From: Leo Simons [mailto:mail@leosimons.com]
> >>
> >>Basically, what you are proposing is to create a hierarchy of
> >>ECMs/ECS rather than a single-level-deep structure, IIUC. The
> >>advantage of this is that using a tree instead of a map results
> >>in better maintainability in larger projects. Right?
> >>
> >
> > That would be one possiblity, and I could make some arguments
> > for this, but what I want is to factor out the "this component
> > can have subcomponents" behavior from ECM/ECS. That is the primary goal.
> >
> > Both ECM and ECS now have a getComponentHandler method, for example.
> > Both of them implements LogKitManageable, Contextualizable etc. for
> > the sole purpose of passing on the obtained LogKitmanager, Context, etc.
> > to the component handlers.
> >
> > What I want to do is create a common superclass for ECM and ECS
> > and move that code there.
> >
> > So to split the questions:
> >
> >  1) Should the common code of ECM and ECS be factored out?
> >     This would make it easier to write ComponentSelectors
> >     and ComponentManagers.
>
>
> Yes, but don't call it AbstractContainer.  It will confuse things
> when the new ContainerManager/Container code is ready for prime
> time.

Berin,

what is your estimate for the ContainerManager/Container code? I
just found it in excalibur.system (had been looking in
excalilbur.container before), and if I'd much rather we got that
stuff going than waste my time with ECM/ECS.

Just a quick check that I understand the code correctly (it is beautiful,
BTW):

If I write a servlet, I'd first grab some parameters from
some file (like, number of threads per CPU, etc...). Since
I want to use the MyComponentManager class, I set CONTAINER_CLASS
to "MyComponentManager", which is a FQCN. Then I do:

    ContainerManager containerManager = new ContainerManager (parameters);

And I now have a completely initialized component manager
inside the containerManager. Then I do a:

    ComponentManager myManager =
        (ComponentManager) containerManager.getContainer ();

and when I want to process a request, I can look up the Processor
(for example) component in myManager and pass it the required parameters.

And now, I want to write a component that holds several other components.

I take it then, that this would be done just as above. The component
would have a CM created via the ContainerManager.

Questions:

1) How do I pass a parent CM to the new CM that I create via the
ContainerManager?
2) How do I pass a non-file Configuration to the ContainerManager? (Useful
in
   the second case.)
3) Will the Container interface be a marker interface? (See question 7).
4) Is it your intention to not use the Lifestyle interfaces ThreadSafe etc.
any more
   and replace them with handler attributes in the configuration file?
5) CONTAINER_CLASS isa component?
6) CONTAINER_CLASS isa Container? Always / must be?
7) Will a component that implements Container be treated in a special way by
the
   Container that contains it? (See question 3).

> Nothing stops you from directly using the ComponentHandler classes.  I
> would suggest you make all of them ThreadSafe, so you don't have any
> funny logic and make things easy on yourself....

That's pretty much my conclusion, too.

But for future work I will need the ContainerManager or something
exactly like that.

/LS



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


Re: [Proposal] ECM / ECS / AbstractContainer

Posted by Berin Loritsch <bl...@apache.org>.
Leo Sutic wrote:
> 
>>From: Leo Simons [mailto:mail@leosimons.com]
>>
>>Basically, what you are proposing is to create a hierarchy of
>>ECMs/ECS rather than a single-level-deep structure, IIUC. The
>>advantage of this is that using a tree instead of a map results
>>in better maintainability in larger projects. Right?
>>
> 
> That would be one possiblity, and I could make some arguments
> for this, but what I want is to factor out the "this component
> can have subcomponents" behavior from ECM/ECS. That is the primary goal.
> 
> Both ECM and ECS now have a getComponentHandler method, for example.
> Both of them implements LogKitManageable, Contextualizable etc. for
> the sole purpose of passing on the obtained LogKitmanager, Context, etc.
> to the component handlers.
> 
> What I want to do is create a common superclass for ECM and ECS
> and move that code there.
> 
> So to split the questions:
> 
>  1) Should the common code of ECM and ECS be factored out?
>     This would make it easier to write ComponentSelectors
>     and ComponentManagers.


Yes, but don't call it AbstractContainer.  It will confuse things
when the new ContainerManager/Container code is ready for prime
time.

> 
>  2) Is it proper for a component to have subcomponents,
>     even if that component is not a ComponentSelector?

Yes!  Absolutely!  That is one of the strengths of design
for Avalon.  Containers can container Containers.  A Container
is merely an object that holds and manages components.

> I'd vote yes to (1) and yes, in some cases, to (2).

Just use proper judgement.  For example, decision trees can
be developed using recursive methods and a snippet of the
configuration tree that has the information in sub configurations.
That was your original issue.

However, in Cocoon's case (which is a perfect example),

the Cocoon component is (should be) a container, and each mountable
sitemap is (should be) a container.  As you can see, there is a
natural heirarchy of containers.



>>The disadvantage is providing unneccessary functionality in
>>simpler setups and degrading performance.
>>
> 
> Performance will not be degraded in the current setup. If you
> use it, you pay for it, otherwise not.

;P  The ExcaliburComponentManager needs some work to become efficient.



>>You should only break IoC if you really need to.
>>Do you?
>>
> 
> Well, the jury in my head is out on that one, as well as whether
> I am in fact breaking IoC, or just avoiding namespace pollution (roles,
> hints) by putting components that I can prove will only *ever* be used by
> one component inside that component.

IoC is ensuring that the container controls the child.  The child should
not initiate communication with the container.  In essence, the child
only responds to the container.

> Suppose you have a component:
> 
>  <component role="General"
>             class="my.generals.Franks"
>             use-strategy="my.strategies.Stealthy"/>
> 
> So the "General" is set to use a strategy defined by my.strategies.Stealthy,
> by instantiating that class and then calling a whatDoIDoNext method on it.
> 
> This does not break IoC.

True.



> That was how I started. Then I figured that maybe the strategy object
> needed to be initialized. And maybe it needed a CM. And a configuration.
> And maybe sub-strategy objects.
> 
> Finally, I was about to write an entire Avalon lifecycle manager for
> the strategy, and since that code already existed in ECM and ECS, well...


Nothing stops you from directly using the ComponentHandler classes.  I
would suggest you make all of them ThreadSafe, so you don't have any
funny logic and make things easy on yourself....


-- 

"They that give up essential liberty to obtain a little temporary safety
  deserve neither liberty nor safety."
                 - Benjamin Franklin


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


RE: [Proposal] ECM / ECS / AbstractContainer

Posted by Leo Sutic <le...@inspireinfrastructure.com>.

> From: Leo Simons [mailto:mail@leosimons.com]
>
> Basically, what you are proposing is to create a hierarchy of
> ECMs/ECS rather than a single-level-deep structure, IIUC. The
> advantage of this is that using a tree instead of a map results
> in better maintainability in larger projects. Right?

That would be one possiblity, and I could make some arguments
for this, but what I want is to factor out the "this component
can have subcomponents" behavior from ECM/ECS. That is the primary goal.

Both ECM and ECS now have a getComponentHandler method, for example.
Both of them implements LogKitManageable, Contextualizable etc. for
the sole purpose of passing on the obtained LogKitmanager, Context, etc.
to the component handlers.

What I want to do is create a common superclass for ECM and ECS
and move that code there.

So to split the questions:

 1) Should the common code of ECM and ECS be factored out?
    This would make it easier to write ComponentSelectors
    and ComponentManagers.

 2) Is it proper for a component to have subcomponents,
    even if that component is not a ComponentSelector?

I'd vote yes to (1) and yes, in some cases, to (2).

> The disadvantage is providing unneccessary functionality in
> simpler setups and degrading performance.

Performance will not be degraded in the current setup. If you
use it, you pay for it, otherwise not.

> You should only break IoC if you really need to.
> Do you?

Well, the jury in my head is out on that one, as well as whether
I am in fact breaking IoC, or just avoiding namespace pollution (roles,
hints) by putting components that I can prove will only *ever* be used by
one component inside that component.

Suppose you have a component:

 <component role="General"
            class="my.generals.Franks"
            use-strategy="my.strategies.Stealthy"/>

So the "General" is set to use a strategy defined by my.strategies.Stealthy,
by instantiating that class and then calling a whatDoIDoNext method on it.

This does not break IoC.

That was how I started. Then I figured that maybe the strategy object
needed to be initialized. And maybe it needed a CM. And a configuration.
And maybe sub-strategy objects.

Finally, I was about to write an entire Avalon lifecycle manager for
the strategy, and since that code already existed in ECM and ECS, well...

/LS


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


RE: [Proposal] ECM / ECS / AbstractContainer

Posted by Leo Simons <ma...@leosimons.com>.
Basically, what you are proposing is to create a hierarchy of
ECMs/ECS rather than a single-level-deep structure, IIUC. The
advantage of this is that using a tree instead of a map results
in better maintainability in larger projects. Right?

The disadvantage is providing unneccessary functionality in
simpler setups and degrading performance.

The question is whether the majority of use cases will be so
complex as to justify the tree approach. I'm guessing this is
not the case. If this is true, I would say that the tree
approach should be an alternative to the standard ECM/ECS.

And to answer your question:
>  - What is the opinion regarding components-that-have-components
> in Avalon?
>    Is this a no-no, with the exception of ComponentSelector?

the idea always has been that components-that-have-components
manage that relationship through a ComponentManager, and
optionally, a ComponentSelector. This to promote Inversion of
Control. You should only break IoC if you really need to.
Do you?

grz,

- LSD

> -----Oorspronkelijk bericht-----
> Van: Leo Sutic [mailto:leo.sutic@inspireinfrastructure.com]
> Verzonden: zondag 3 maart 2002 22:52
> Aan: Avalon Developer's List
> Onderwerp: [Proposal] ECM / ECS / AbstractContainer
>
>
> All,
>
> there is a lot of code duplicated between the
> ExcaliburComponentManager and
> the
> ExcaliburComponentSelector. Basically, they both implement
> Contextualizable,
> Composable (ECM only), RoleManageable and LogKitManageable. These
> interfaces
> are just implemented in order to pass on the context etc. to the
> ComponentHandlers.
>
> The code for this is also very useful for any other
> Component-that-has-subComponents.
>
> My example is this:
>
> I have a component that will use the strategy pattern. That is, it has a
> method
> that is something like this:
>
>   public Action whatToDoNext (Context context);
>
> So, given something, it will return an action for the context. Now comes
> the fun part: It solves this by having another component within itself
> that it passes the context on to and recieves an Action in return.
>
> *That* component may in turn have sub-components.
>
> So, I end up with a decision tree where the nodes are components.
>
> For example, suppose we want to do A in the afternoon and B
> otherwise, with
> the exception that instead of B, we should do C on Sundays.
>
>                       Sunday +--------------- C
>                              |
>             AM +-------- DayOfWeek ---------- B
>                |                     Otherw.
> Root ---- TimeOfDay
>                |
>             PM +--------- A
>
>
> Each node in the tree would be a component, that could possibly have
> subcomponents.
>
> The configuration would look like this:
>
> <tree-root>
>   <rule class="TimeOfDay">
>       <when start="0" end="12">
>           <rule class="DayOfWeek">
>               <when start="Monday" end="Saturday">
>                   <action class="B"/>
>               </when>
>               <when start="Sunday" end="Sunday">
>                   <action class="C"/>
>               </when>
>           </rule>
>       </when>
>       <when start="12" end="24">
>           <action class="A"/>
>       </when>
>   </rule>
> </tree-root>
>
> In Cocoon this is solved by looking up the matchers (equivalent to the
> DayOfWeek and
> TimeOfDay classes in the example) via a ComponentSelector, and passing a
> pattern
> to them. This is suboptimal when each component instance in the selector
> is only used in one place and I would end up with the following
> instances in
> the Selector:
>
> <rule hint="root" class="TimeOfDay">
>   <when start="0" end="12" then="day-of-week"/>
>   <when start="12" end="24" then="A"/>
> </rule>
> <rule hint="day-of-week" class="DayOfWeek">
>   <when start="Monday" end="Saturday" then="B"/>
>   <when start="Sunday" end="Sunday" then="C"/>
> </rule>
> <rule hint="A" class="FireA"/>
> <rule hint="B" class="FireB"/>
> <rule hint="C" class="FireC"/>
>
> Of course, if we want to select between weekdays in another part of the
> tree - say, do D instead of A on Saturdays, we get an additional:
>
> <rule hint="day-of-week-saturday" class="DayOfWeek">
>   <when start="Sunday" end="Friday" then="A"/>
>   <when start="Saturday" end="Saturday" then="D"/>
> </rule>
>
> (And don't forget to update the hint="root" rule to reference this new
> rule!)
>
> And so on. As the tree gets flattened, maintainability is lost,
> and I would
> like
> to solve this by allowing each component to have sub-components,
> just like a
> ComponentSelector can select among several sub-Selectors.
>
> This would also allow for powerful rule-based ComponentSelectors to do
> N-dimensional
> lookups, where the rules need not be coded into the ComponentSelector.
>
> THE PROPOSAL:
>
> Attached is an implementation of AbstractContainer and
> ExcaliburComponentManager,
> modified to inherit from AbstractContainer.
>
> The AbstractContainer class gathers all the references necessary to create
> ComponentHandlers - it does nothing more. What happens with the handlers
> is up to the subclass.
>
> I propose that this replace the current implementation of ECM,
> that the ECS
> is rewritten to derive from AbstractContainer, and that AbstractContainer
> is make part of Excalibur.
>
> I am not calling a vote just yet.
>
> I am also looking for input regarding:
>
>  - What is the opinion regarding components-that-have-components
> in Avalon?
>    Is this a no-no, with the exception of ComponentSelector?
>
> /LS
>


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