Re: Data model traverse
Daniel Dekany <[email protected]>
| Newsgroups | gmane.comp.web.freemarker.user |
|---|---|
| Message-ID | <[email protected]> |
Monday, March 30, 2009, 4:37:31 PM, wkbutler wrote:
>
>
> Daniel Dekany wrote:
>>
>>>Saturday, March 28, 2009, 12:48:36 AM, Daniel Dekany wrote:
>>>> Friday, March 27, 2009, 5:44:46 PM, wkbutler wrote:
>>>>>
>>>>> Thanks Daniel. Maybe data_model has been overridden then, because when
>>>>> I use
>>>>> your suggestion this is the error I encounter:
>>>>>
>>>>> Caused by: freemarker.template.TemplateException: Expected extended
>>>>> hash.
>>>>> .data_model evaluated instead to freemarker.co
>>>>> re.Environment$1 on line 3, column 10 in
>>>>> appfuse/web/struts/action-test.ftl.
>>>>> at
>>>>> freemarker.core.TemplateObject.invalidTypeException(TemplateObject.java:135)
>>>>> at
>>>>> freemarker.core.BuiltIn$keysBI._getAsTemplateModel(BuiltIn.java:594)
>>>>> at
>>>>> freemarker.core.Expression.getAsTemplateModel(Expression.java:89)
>>>>> at freemarker.core.IteratorBlock.accept(IteratorBlock.java:87)
>>>>> at freemarker.core.Environment.visit(Environment.java:196)
>>>>> at freemarker.core.MixedContent.accept(MixedContent.java:92)
>>>>> at freemarker.core.Environment.visit(Environment.java:196)
>>>>> at freemarker.core.Environment.process(Environment.java:176)
>>>>> at freemarker.template.Template.process(Template.java:232)
>>>>> at
>>>>> org.hibernate.tool.hbm2x.TemplateHelper.processTemplate(TemplateHelper.java:255)
>>>>
>>>> Now that's magical, in a bad way. What does ${.version} print? Because
>>>> it seems I will have to find out what Envionment$1 is... (Currently
>>>> it's a TemplateDirectiveBody, and I could achieve this error message
>>>> with a trick, but the stack trace doesn't suggest that the error was
>>>> achieved with my trick...) Can you access any data-model variables at
>>>> all in this template? I guess you can't.
>>>
>>>Anyway, a quick guess... I remember that in some older FM versions the
>>>data-model wasn't TemplateHashModelEx. So maybe it's an old FM
>>>version, and there Environment$1 was some anonymous TemplateHashModel
>>>used to wrap the data-model... So, replace freemarker.jar with a
>>>recent one, and if the problem goes away, then that was it.
>>>
>>
>
>
> We are running struts2-core 2.0.11, which uses FM 2.3.8. Upgrading to struts
> 2.1.x would get us up to FM 2.3.13, which could be worthwhile. The
> ${.version} tag confirmed the runtime version at 2.3.8.
.data_model?keys works (in most cases) starting from 2.3.11 only
(http://freemarker.org/docs/versions_2_3_11.html). But, at least
technically, you don't need to update Struts for updating FreeMarker,
since the 2.3-series keep backward compatibility. Just add FreeMarker
2.3.15 as a project dependency... if you are using Maven or Ivy, that
is.
> And sorry, I did not divulge this at the outset, but FM is being invoked
> here by hibernate3's hbm2java tool.
>
> So, in fact the data model objects are accessible.
Yeah, that was expected after I realized what the problem was.
> Here is what I believe to
> be the relevant source:
>
> protected Configuration freeMarkerEngine;
> protected SimpleHash getContext()
> {
> return context;
> }
> public void setupContext()
> {
> getContext().put("version", Version.getDefault());
> getContext().put("ctx", getContext());
> getContext().put("templates", new Templates());
> getContext().put("date", new SimpleDate(new Date(), 3));
> }
> public void processTemplate(String templateName, Writer output, String
> rootContext)
> {
> if(rootContext == null)
> rootContext = "Unknown context";
> try
> {
> Template template =
> freeMarkerEngine.getTemplate(templateName);
> template.process(getContext(), output);
> }
> catch(IOException e)
> ...
> }
>
> I think the rootContext is getting passed as a fully-qualified class name.
>
> Anyhow if I use the following trace:
>
> Version: ${.version}
> The version variable in the data-model: ${version}
> The templates variable in the data-model: ${templates}
> The date variable in the data-model: ${date}
>
> The variables in the ctx data-model are:
> <#list ctx?keys as key>
Indeed, you are lucky here as the data-model is put into itself(!)
with name "ctx" in this application, so that's a workaround...
> ${key?html}
> </#list>
>
> I get...
>
> Version: 2.3.8
> The version variable in the data-model: 3.2.2.GA
> The templates variable in the data-model:
> org.hibernate.tool.hbm2x.TemplateHelper$Templates@133926
> The date variable in the data-model: Mar 30, 2009 9:53:07 AM
>
> The variables in the ctx data-model are:
> com.h4h.model.RateProgram
> basepackage
> data
> ...rest of my data model...
>
>
> and if I iterate over the keys of ${version} and ${templates}, the keys are
> the get methods of those objects. No surprise there, I suppose. But, this
> helps a lot because now I have a path to examining and modifying the data
> model.
>
> So I understand how this is working much better. When I get struts updated
> I will try to re-test and see if .data_model becomes available.
>
> Otherwise, I guess we can conclude that the clever lads at hibernate have
> not done anything so exotic with FM, right?
Not to my knowledge...
> "Pretty standard, really". Thanks for all your help Daniel. Hope
> this helps someone else too.
>
> Kent
--
Best regards,
Daniel Dekany
------------------------------------------------------------------------------