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