in the code below,

ViewContext vctx = (ViewContext) context;

should read:

ViewContext vctx = (ViewContext) context.getInternalUserContext();

and this is fine, as long as the directive is being used with VelocityView.

C

> -----Original Message-----
> From: Townson, Chris [mailto:[EMAIL PROTECTED] 
> Sent: 10 January 2007 09:31
> To: Velocity Users List
> Subject: RE: VelocityView and toolbox - location of tool instance
> 
> okay, I think I see why this doesn't work:
> 
> the directive's init() does not receive the same context as 
> render() - at the point of init() we just have a standard 
> VelocityContext (it looks like the parser is just 
> initializing a tree at this point)
> 
> ... only once we reach render, do we have the actual context: 
> if I move the code which retrieves the tool into the render 
> method, it works:
> 
> public class CustomDirective extends InputBase
> {
>     public String getName()
>     {
>         return "custom";
>     }
> 
>     public int getType()
>     {
>         return LINE;
>     }
> 
>     public void init(RuntimeServices rsvc, 
> InternalContextAdapter context,
>             Node node) throws TemplateInitException
>     {
>         super.init(rsvc, context, node);
>     }
> 
>     public boolean render(InternalContextAdapter context, 
> Writer writer, Node node)
>             throws IOException, ResourceNotFoundException, 
> ParseErrorException,
>             MethodInvocationException
>     {
>         try
>         {
>             MyTool tool = (MyTool) context.get("mytool");
>         }
>         catch (Exception e)
>         {
>             // handle ClassCastException here
>         }
> 
>         if (tool != null)
>         {
>             try
>             {
>                 String arg0 = (String) 
> node.jjtGetChild(0).value(context);
>                 Map arg1 = (Map) node.jjtGetChild(1).value(context);
>                 ViewContext vctx = (ViewContext) context;
>                 HttpServletRequest request = vctx.getRequest();
> 
>                 MyObject obj = tool.getMyObject(arg0, arg1, request);
> 
>                 Context ctx = new VelocityContext();
>                 ctx.put("this", obj);
>                 Template template = 
> rsvc.getTemplate(obj.getTemplate());
>                 template.merge(ctx, writer);
>                 return true;
>             }
>             catch (Exception e)
>             {
>                 return false;
>             }
>         }
>         else
>         {
>             return false;
>         }
>     }
> }
> 
> > -----Original Message-----
> > From: Townson, Chris [mailto:[EMAIL PROTECTED] 
> > Sent: 09 January 2007 18:49
> > To: Velocity Users List
> > Subject: RE: VelocityView and toolbox - location of tool instance
> > 
> > yep - I was surprised, too.
> > 
> > I made an assumption about the context provided to the 
> > directive's render() method (InternalContextAdapter) - that 
> > it was basically the context being used to render the current 
> > template in which the directive was invoked ... however, this 
> > does not appear to be the case. In fact, on close 
> > examination, it does not even appear to contain or provide a 
> > reference to this context ... which seems strange to me.
> > 
> > It must surely be possible to retrieve objects from the 
> > context with which the current template is being merged from 
> > a directive's render() method ... the question is "how?" I 
> > get the feeling that I must be missing something very obvious 
> > in my code. Here is what I am trying to do, slightly abbreviated:
> > 
> > 
> > public class CustomDirective extends InputBase
> > {
> >     public String getName()
> >     {
> >         return "custom";
> >     }
> > 
> >     public int getType()
> >     {
> >         return LINE;
> >     }
> > 
> >     public void init(RuntimeServices rsvc, 
> > InternalContextAdapter context,
> >             Node node) throws TemplateInitException
> >     {
> >         super.init(rsvc, context, node);
> > 
> >         try
> >         {
> >             MyTool tool = (MyTool) context.get("mytool");
> >         }
> >         catch (Exception e)
> >         {
> >             throw new TemplateInitException(e.getMessage(),
> >                     context.getCurrentTemplateName(),
> >                     node.getColumn(),
> >                     node.getLine());
> >         }
> >     }
> > 
> >     public boolean render(InternalContextAdapter context, 
> > Writer writer, Node node)
> >             throws IOException, ResourceNotFoundException, 
> > ParseErrorException,
> >             MethodInvocationException
> >     {
> >         if (tool != null)
> >         {
> >             try
> >             {
> >                 String arg0 = (String) 
> > node.jjtGetChild(0).value(context);
> >                 Map arg1 = (Map) node.jjtGetChild(1).value(context);
> >                 ViewContext vctx = (ViewContext) context;
> >                 HttpServletRequest request = vctx.getRequest();
> > 
> >                 MyObject obj = tool.getMyObject(arg0, arg1, 
> request);
> > 
> >                 Context ctx = new VelocityContext();
> >                 ctx.put("this", obj);
> >                 Template template = 
> > rsvc.getTemplate(obj.getTemplate());
> >                 template.merge(ctx, writer);
> >                 return true;
> >             }
> >             catch (Exception e)
> >             {
> >                 return false;
> >             }
> >         }
> >         else
> >         {
> >             return false;
> >         }
> >     }
> > }
> > 
> > 
> > this would go with a toolbox that looked something like:
> > 
> > <?xml version="1.0" encoding="UTF-8"?>
> > <toolbox>
> >     <tool>
> >         <key>mytool</key>
> >         <scope>request</scope>
> >         <class>foo.bar.MyTool</class>
> >     </tool>
> > </toolbox>
> > 
> > 
> > and the instance of "MyObject" knows it's own template name 
> > and has a template like this:
> > 
> > <ul>
> >     <li>$this.property</li>
> >     <li>$this.anotherProperty</li>
> >     <!-- ... and so on ... -->
> > </ul>
> > 
> > 
> > Any suggestions / pointers / explanations of why this doesn't 
> > work would be much appreciated.
> > 
> > Cheers,
> > 
> > Chris
> > 
> > > -----Original Message-----
> > > From: Nathan Bubna [mailto:[EMAIL PROTECTED] 
> > > Sent: 04 January 2007 19:03
> > > To: Velocity Users List
> > > Subject: Re: VelocityView and toolbox - location of tool instance
> > > 
> > > I'm a little surprised that the method you tried is failing.  I
> > > haven't written many custom directives though, so i'm not 
> > sure how to
> > > help.   Does anyone else out there know why the context 
> provided to
> > > the directive wouldn't have access to the tools?
> > > 
> > > That said, where instantiated tools is kept varies 
> according to the
> > > scope.  Application scoped tools are currently kept in a private
> > > HashMap in ServletToolboxManager.   Session-scoped tools 
> > are kept in a
> > > HashMap placed into the user's session attributes.  Both 
> application
> > > and session tools are copied into the toolbox Map for the request,
> > > where they are joined by the freshly-instantiated request 
> > tools.  The
> > > toolbox Map is then fed to the ChainedContext for the 
> > request.  Which,
> > > i would have thought, ought to be accessible from the 
> > directive, since
> > > that is the context merged with the requested template.
> > > 
> > > On 1/4/07, Townson, Chris <[EMAIL PROTECTED]> wrote:
> > > > Hi,
> > > >
> > > > I think this is a simple question ... although I could be 
> > > having one of those winter, late-afternoon brain-dead moments ...
> > > >
> > > > Whereabouts exactly are tool class instances kept once they 
> > > have been initialized when using VelocityView and 
> > > toolbox.xml? In other words, from where and how does one 
> > > obtain a reference to that tool instance (in another class, 
> > > not in a template)?
> > > >
> > > > For example, if I have a custom directive and want to 
> > > retrieve a previously initialized instance of an 
> > > application-scope tool, how would I do this?
> > > >
> > > > Initially I thought that this would be achieved in the 
> > > following way:
> > > >
> > > > in the toolbox:
> > > > <tool>
> > > >   <key>myTool</key>
> > > >   <scope>application</scope>
> > > >   <class>com.foo.MyReallyGroovyTool</class>
> > > > </tool>
> > > >
> > > > in a directive:
> > > > public CustomDirective extends InputBase {
> > > >   ...
> > > >
> > > >   public void init(RuntimeServices rsvc, 
> > > InternalContextAdapter context, Node node) throws 
> > > TemplateInitException {
> > > >     MyReallGroovyTool tool = (MyReallyGroovyTool) 
> > > context.get("myTool");
> > > >   }
> > > >
> > > >   ...
> > > > }
> > > >
> > > >
> > > > but now I'm thinking this is not correct (and trying this 
> > > way fails) ...
> > > >
> > > > Cheers,
> > > >
> > > > Chris
> > > >
> > > > 
> > 

********************************************************************************
   
DISCLAIMER: This e-mail is confidential and should not be used by anyone who is
not the original intended recipient. If you have received this e-mail in error
please inform the sender and delete it from your mailbox or any other storage
mechanism. Neither Macmillan Publishers Limited nor any of its agents accept
liability for any statements made which are clearly the sender's own and not
expressly made on behalf of Macmillan Publishers Limited or one of its agents.
Please note that neither Macmillan Publishers Limited nor any of its agents
accept any responsibility for viruses that may be contained in this e-mail or
its attachments and it is your responsibility to scan the e-mail and 
attachments (if any). No contracts may be concluded on behalf of Macmillan 
Publishers Limited or its agents by means of e-mail communication. Macmillan 
Publishers Limited Registered in England and Wales with registered number 
785998 
Registered Office Brunel Road, Houndmills, Basingstoke RG21 6XS   
********************************************************************************

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

Reply via email to