"Patrick E. Whitesell" wrote:
>
> Hmm... I do have to agree that using a separate class does open up
> possibilities and help alleviate concerns. I was thinking of doing
> something like that at first, but it didn't seem as "elegant."
I know what you are feeling. It seems to be one of those tradeoffs
between elegance and complexity, and when you stand back, the
alternative solution isn't so bad.
(And an example of elegance taken too far, in my opinion, is the Java
data and calendering APIs. Beautiful design. Throughly unusable for
casual use.)
> But
> thinking about it more it does make a lot of sense, both for the ability
> to create a more robust class, and to keep the "read only" contract
> strictly enforcable.
Yep. And prevents clouding the Context interface with methods that are
structural rather than data-centric.
>
> What exactly is the "node specific introspection caching" mentioned in
> the docs? Would it be worth it to put a class like this on the Context
> tree, versus subclassing ArrayList or something like that to get more
> functionality for free?
No. That stuff is related to internal functionality of collection
introspection information as the context wanders around the syntax tree,
and the implementation is such that the two are separate. Think of it
as if there are two parts to the context that actually is passed to
each syntax node, an internal context, and the user data context.
Keeping them separate means that we can modify the internal context as
needed w/o requiring change to the user data context implentations and
interfaces.
What it does is take advantage of the fact that the context is really a
thread-safe storage unit during the duration of the merge, so it uses
that to keep introspection information 'close'. Think of it as the L1
cache in a microsprocessor - small and local to the currently running
thread - versus the L2 cache, which is analagous to our global
introspection cache.
So take a wack at it if you want. I'm not sure how all will feel about
inclusion as a regular part of Velocity (I'm not sure how I feel, as I
am not sure how common this problem is.) But it is a nifty utility
class, so at worst, we can keep it as a contrib.
geir
>
> --
> Patrick
>
> Geir Magnusson Jr. wrote:
>
> > "Patrick E. Whitesell" wrote:
> >
> >> Basically, I wanted to create a context chain where the most recently
> >> created context was not necessarily at the head of the chain. These
> >> changes allow me to do that.
> >
> >
> > Well, there are alternatives. One thing that bugs me, beyond the chance
> > that someone cooks up an infinite loop, is that you can't assume anymore
> > that a context is 'read only' when chained, which I think is important.
> >
> > To illustrate, suppose you have a framework of some type that
> > instantiates and populates a toolbox context, something containing
> > common tools to be used by a request. By being able to 'add to the end'
> > of the chain, you can effectively modify that toolbox. Not good. Yes,
> > you can claim that you will remember to clean up, but I woudn't want to
> > bank on it as a framework.
> >
> > An alternative, I think, would be a little helper Context that allows
> > you to add contexts in any order, and insert them anywhere, but in doing
> > so, doesn't assume anything about the contexts its working with.
> >
> > Instead of
> >
> > C -> ToolboxContext -> YourContext
> >
> > have
> >
> > C -> ToolboxContext
> > |
> > -> YourContext
> >
> > so you get the same result w/o fear of screwing someone else up.
> >
> > As a quickie example, suppose you had something like : (and forgive any
> > gaffes - I am winging it here with beer in hand...)
> >
> > public class ContextChainer implements Context
> > {
> > private ArrayList inner = new ArrayList();
> > private HashMap myData = new HashMap();
> >
> > /*
> > * add context to the vector at some position
> > */
> > public Context addContext( int pos, Context c )
> >
> > /*
> > * remove context from some position
> > */
> > public Context removeContext( int pos );
> >
> >
> > /*---- Context interface --- */
> >
> > public Object get( String key )
> > {
> > // check local
> >
> > Object o = myData.get( key );
> >
> > if ( o == null)
> > {
> > // go through the list..
> >
> > Iterator i = inner.iterator();
> >
> > while( i.hasNext() )
> > {
> > Context c = (Context) i.next();
> > o = c.get( key );
> > if( o != null)
> > return o;
> > }
> > }
> >
> > return o;
> > }
> >
> > etc...
> > }
> >
> >
> > Now, the advantages here is that
> >
> > 1) you can place your contexts in any order
> > 2) you can remove them as well
> > 3) you don't modify anyone elses context
> > 4) I don't fear a loop :)
> >
> > It also means that all sorts of interesting [goofy] constructs can be
> > made :
> >
> > C -> ToolboxContext -> Toolbox2
> > |
> > -> YourContext
> > |
> > -> AnotherToolbox -> C1
> > |
> > -> C2
> >
> > Comments?
> >
> > geir
> >
> >
> >> Geir Magnusson Jr. wrote:
> >>
> >>
> >>> Could you provide some information what problems you were trying to
> >>> solve, or what you are trying to enhance? That would be great.
> >>>
> >>> geir
> >>>
> >>>
> >>> "Patrick E. Whitesell" wrote:
> >>>
> >>>
> >>>> Hey fellas,
> >>>>
> >>>> I did some stuff to enchance the Context chaining. This is my first
> >>>> submission, so let me know if I'm way out of line...
> >>>>
> >>>> There are some ugly bits in here due to the fact that the innerContext
> >>>> is defined as a Context, not an AbstractContext. Does anyone object to
> >>>> making the innerContext an AbstractContext? If not, I can take the
> >>>> exceptions out of this code...
> >>>
--
Geir Magnusson Jr. [EMAIL PROTECTED]
System and Software Consulting
Developing for the web? See http://jakarta.apache.org/velocity/