Leon Messerschmidt wrote:

> 3.  Where to add the functionality.  I was (and still am) in favour of
> adding a single InsertionListener to the Context. 

I want more, and not bolted onto Context.

> 
> 4.  Chaining InsertionListeners.  I think Chaining can negatively affect
> performance.  

I agree that it can, but so can listeners.  I am sure the next one-off
use will want this, and it places no burden on the listener writer. (See
below)

> [VOTE]  Implement the an InsertionListener as mentioned above.  i.e. a
> single Listener added to the Context.  A final performance test will
> determine whether the code makes it's way into Velocity.
> +1
> 

-1 as mentioned :)

Here's what I vote +1 for (you'll be happy, I hope...).  I was going to
get it in last night, but wife came home after a business trip, so that
wasn't cool to sit around and do Velocity :

What I would like to see, and will upload to the whiteboard the
implementation right after this post is the something I called an
EventCartridge  (for lack of a better name) with an app level API :

public class EventCartridge
{
  /** add a handler to the cartridge */
  public boolean addEventHandler( EventHandler ev )
 
  /** attach the cartridge to the context */
  public boolean attachToContext( Context context )
}

And I currently have two event handlers :

For Leon and Chris Kimpton (and we can split this up into two separate
handlers) :

public interface  ReferenceInsertionEventHandler extends EventHandler
{
  /** called right before inserting a reference val to stream */
  public String referenceInsert( String reference, String value  );

  /** called when a ref evals to null to determine if render - 
   *  think of it as a 'dynamic Quiet reference'  */ 
  public boolean nullReferenceRender( String reference );
}

For Christoph :

public interface NullSetEventHandler extends EventHandler
{
    /** approve/reject log message for #
     * set($foo = <eval to null>) situation */
    public boolean nullSetLogMessage( String reference );
}

and we can design more as needed.

How it's used by a user - as a hokey illustrative example :

public class Test implements ReferenceInsertionEventHandler,
NullSetEventHandler
{
  public void someMethod()
  { 
    ....
   VelocityContext context = new VelocityContext();
   
   ..<add stuff>..

   EventCartridge ec = new EventCartridge();
   ec.addEventHandler(this);
   ec.attachToContext( context );
   ...
   .. <do rendering>..
  }
  
  public boolean nullReferenceRender( String reference )
  {
    if( reference.equals("$gloppy"))
      return false;

    return true;
  }
       
  public String referenceInsert( String reference, String value  )
  {
    System.out.println("Woo! referenceInsert : " + reference + " = " +
value );
    return value;
  }

  public boolean nullSetLogMessage( String reference )
  {
     System.out.println("Woo2! nullSetLogMessage : " + reference);

     if (reference.equals("$woogie"))
            return false;
        
     return true;
  }
}

You can guess what these do.  

For a user not using events, the cost is one method call per node at
render time at most ( and if that is too expensive, can reduce to a
field access.

For a user using events, there is an additional method call per
'listener' to determine if any listeners are registered for that node.

So it's relatively cheap, yet pretty flexible.  Also, as time goes on,
we can add functionality w/o breaking the public API in any way, which
is important.  Just drop in a new jar and go - if you want to use a new
listener type if we add one, great.  If not, don't worry - your code
says the same.

I will upload the relevant bits and a working jar to my whiteboard
directory.  I won't upload all the parts as it touches quite a few
internal context bits, and they aren't relevant for discussion, and I
prollie can't find them easily :)  I want to do some renaming work in
the context space anyway, so will do that then if we want to go this
way, knocking off two birds...

Leon, can you test with it to see if it is along the lines of what you
were thinking?

Note that this was scratch code playing with Chris Kimpton's
suggestions, so things aren't perfect or polished....

geir
 
-- 
Geir Magnusson Jr.                               [EMAIL PROTECTED]
Developing for the web?  See http://jakarta.apache.org/velocity/

Reply via email to