On Tue, Apr 8, 2008 at 2:10 PM, Charles Harvey III <[EMAIL PROTECTED]> wrote:
> Ok. I tried and tried and I cannot get the ServletConfig to where I need it
> so
> I can create a new VelocityView. The best I can get is a ServletContext.
That is a bummer. Thank you! Seriously, this exposes a signficant
shortcoming in the plans to make it easy to integrate Tools into other
frameworks. It also made me realize that i didn't provide proper
Filter support either. It needs to be easier to init() a VelocityView
(whether with a ServletConfig, FilterConfig or neither). I'll try to
set aside some time to fix that this week. It'll mean we need to do
another beta, i'm sure, but i think it'll be well worth it.
> ------------------------------------------------------------------
> VelocityView velocityView = new VelocityView( getServletContext() );
> Context context = velocityView.getContext( request, response );
> ------------------------------------------------------------------
>
> And, looking at the code for VelocityView, when you create a new
> VelocityView
> with a ServletContext, it never calls the init(ServletConfig config)
> method.
> So, the tools don't get configured. When I do $params.get('thing') it
> tells me:
>
> Request is null. ParameterTool must be initialized first!
Actually, this means the tools did get configured. This just means
that the tool was never given access to the HttpServletRequest; the
tools aren't being properly initialized.
You could just precede $params.thing with $params.setRequest($request)
to make this work, but obviously that shouldn't be necessary and would
not work for tools who use configure() instead of setters.
> So, I tried it the "standalone" way:
> ------------------------------------------------------------------
> ToolManager manager = new ToolManager();
> if( getToolboxConfigLocation() != null )
> {
> manager.configure( getServletContext().getRealPath(
> getToolboxConfigLocation() ) );
> }
> manager.setVelocityEngine( getVelocityEngine() );
> Context context = manager.createContext();
> ------------------------------------------------------------------
>
> And I get the same result.
As expected. The code above has no knowledge of ServletRequests, so
it would be unable to tell tools about them.
> One other attempt was made:
> ------------------------------------------------------------------
> ViewToolContext context = new ViewToolContext( getVelocityEngine(),
> request, response,
> getServletContext() );
> ------------------------------------------------------------------
>
> This time, no errors. But the tools don't work. I see a bunch of
> $link.setRelative()
> all over the page. Nothing renders.
That's because the ViewToolContext only knows how to find tools. It
doesn't create them at all.
>
> Am I close? Way off? Any help is much appreciated.
>
Your last example is actually headed in the right direction.
Unfortunately, since you can't use VelocityView until i fix it, it's a
little more complicated. Here's the gist, though i'll have to leave
you to fill in the blanks for the moment:
the first goal is to create a FactoryConfiguration, then configure a
new ToolboxFactory instance with that config. this may look something
like this (see VelocityView.configure(ServletConfig, ToolboxFactory)
for a much more involved example):
FactoryConfiguration config = ConfigurationUtils.getAutoLoaded(); //
read javadoc on this!
ToolboxFactory factory = new ToolboxFactory();
factory.configure(config);
keep this factory around for the life of the app. you only want the
code above to happen once, not on every request!
this once-per-app initialization is also a good place to create your
application-scoped toolbox and put that in the servlet context. that
code is ripped from VelocityView.init(ServletConfig,ToolboxFactory)
and looks roughly like this:
Toolbox appTools = factory.createToolbox(Scope.APPLICATION);
if (appTools != null &&
servletContext.getAttribute(Toolbox.class.getName()) == null)
{
servletContext.setAttribute(Toolbox.class.getName(), appTools);
}
with that, the application level stuff should be ready to go; now we
just need to prep some things before every request. so, before you
create that ViewToolContext in your last example above, use your
ToolboxFactory and do the following (this code is ripped from
VelocityView.prepareToolboxes()):
String key = Toolbox.class.getName();
if (factory.hasTools(Scope.REQUEST)
&& request.getAttribute(key) == null)
{
// add request toolbox, if any
Toolbox reqTools = factory.createToolbox(Scope.REQUEST);
if (reqTools != null)
{
request.setAttribute(key, reqTools);
}
}
if (factory.hasTools("session"))
{
HttpSession session = request.getSession(true);
// allow only one thread at a time
synchronized(factory)
{
if (session.getAttribute(key) == null)
{
Toolbox sessTools =
factory.createToolbox("session");
session.setAttribute(key, sessTools);
}
}
}
This creates the Toolbox instances for the current session and request
and puts them where the ViewToolContext can find them. Once all of
the above is done, create your ViewToolContext and return that.
i think that should do the trick. sorry this is more complicated that
i'd hoped. i'll try and whip the VelocityView init code into
something more forgiving and get a new beta out. Thanks for bringing
attention to this deficit. :)
> Thanks again.
>
>
>
>
> Charlie
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: [EMAIL PROTECTED]
> For additional commands, e-mail: [EMAIL PROTECTED]
>
>