Leo Sutic wrote:

>>After looking at this, we have a problem.
>>
>>The Resolver needs to be set to work with the new Context root
>>directory.
>>
>>There are a couple things that got somewhat broken, so here is my
>>approach to fixing it:
>>
>>The ContextBuilder can be initialized with a rootContext, or it can
>>create a default all by itself.
>>
>>The ContextManager *only* has one root context.  Whether it is a regular
>>Context object created by hand or one from ContextBuilder makes no
>>difference.  The overrides for the key pieces are done in ContextBuilder
>>anyway.
> 
> 
> Yes, but the way the overrides work makes this difficult. Suppose you start
> by setting a LOGGERMANAGER_CONFIG in the context. So the Context looks like
> this:
> 
>   LOGGERMANAGER_CONFIG: Configuration
>   CONTEXT_DIR: File
>   ...other defaults...
> 
> Now this gets passed to the ContextManager. It uses the LOGGERMANAGER_CONFIG
> to create a logger manager.
> 
>   LOGGERMANAGER: LoggerManager
>   LOGGERMANAGER_CONFIG: Configuration
>   CONTEXT_DIR: File
>   ...other defaults...


The answer to your problem is not in merging two *root* contexts.
Especially when you don't do it soon enough.  The answer is to have
a new Context object that can remove access to a value--even in the
parent context.

Example:

OverridableContext extends DefaultContext
{
     void put(String key, Object value)
     {
         // In effect covers the old value with "" so we never
         // look at the parent.
         super.put( key, (value == null) ? "" : value );
     }

     void Object get(String key)
     {
         Object retVal = super.get( key );

         if ( "".equals( retVal ) )
         {
             throw new ContextException("Could not find the value");
         }
     }
}

That way, we can use the ContextBuilder to override certain things,
and keep access from the parent context in that regard.

Unless anybody has problems with this, that is the approach I will
take.


> So, does the ContextManager create a new LoggerManager or not? It should,
> but does
> it use the Configuration or the URL? Whatever your answer, rearrange the
> above
> if needed to get a case where the answer is wrong.
> 
> The whole approach with passing everything in via a context was *wrong* and
> is
> *a total mess*.
> 
> Let's look at this flow backwards.
> 
> The Container inside the ContainerManager needs (all of these optional):
> 
>   Configuration
>   Context
>   ComponentManager
>   LoggerManager
>   Logger
>   Resolver
> 
> The problem is that in order to make it easy on the application writer,
> we want the ContainerManager to be able to set most of these up given
> some basic information. For example, the Configuration can be passed in
> as-is, or it can be built from a URI (resolved via the resolver). It is
> also possible to inherit any of these from the parent (LoggerManager,
> ComponentManager). It is also necessary to create these in a specific
> order (LoggerManager before Logger), so the actual creation must be done
> inside the ContainerManager and hidden.
> 
> The mistake was trying to pass *all* of this in through a Context.

Ok.  Granted, I am only passing reference to the management items
through the context.



> What if we instead had:
> 
> class ContainerManager {
>   public ContainerManager (ComponentManagerBuilder ccm, LoggerManagerBuilder
> clm, ... ) {
>   }
> }
> 
> class ComponentManagerBuilder {
>     private final static int USE_EXISTING = 0;
>     private final static int BUILD_FROM_CONFIG = 1;
>     private final static int BUILD_FROM_PARENT_AND_CONFIG = 2;
>     ...
> 
>     public ContainerComponentManager (ComponentManager useExisting) { ... }
>     public ContainerComponentManager (Configuration config) { ... }
>     public ContainerComponentManager (ComponentManager parent, Configuration
> config) { ... }
> 
>     /**
>      * Creates a CM.
>      */
>     public ComponentManager build (Resolver resolver /* just in case */) {
> ... }
> }

Keep in mind that I am trying to make it easier on the application
developer.  Not necessarily us.



> Now, the ContainerManager would know what items to build and what to just
> pass along without polluting the context.
> 
> I think we're trying to be just a little bit too smart here. What the
> client needs to be able to say is: Right, I want a container. This is the
> container
> Class, this is the Context for it, I have no LoggerManager so you build it
> from this
> configuration, I have a log category and it is "...." and I'll just go
> with the defaults for the rest.
> 
> So, looking at the stages of creating a Container, what needs to be finished
> first?
> 
> I'd argue for this order:
> 
>   Resolver
>   Configuration
>   ComponentManager
>   LoggerManager
>   Logger
>   Context

:/

You need to understand one thing:

The Resolver *uses* the context to determine where the root context of
the system is.  That is why there is a root context and a context that
is passed to the ContainerManager.

Also, The LoggerManager needs the same information.  Furthermore, the
Resolver needs the proper Logger.

I'd argue for this order:

(Root) Context
LoggerManager
Logger
Resolver
ComponentManager
Configuration
Context

The things you have to remember are that the LoggerManager needs a
context object for some of the things it does.  The Resolver needs
the proper logger, the ComponentManager for the Container *requires*
the Resolver generated in the ContainerManager.  The ContainerManager
*must* have it's *own* Resolver for *each* Container.  The Context
root will be different.  That is something your initial implementation
ignored.

It is also confusing to have two contexts passed in.  Which one takes
precedence?  With only one context, there are fewer questions to have
to answer over and over again.  I am thinking of users of the API.

> Each of these can be "use this instance", "build one instance from <type>"
> or
> "going with defaults (ContainerManager creates new default instances or
> tries to find it in the context or something)".

And we can "turn off" contextual information that we do not want from
the parent.


-- 

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


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

Reply via email to