Load freemarker template from classpath - spring-mvc

I have a Resource in aSpring MVCapplication loaded from the classpath.
<bean id="myController" class="com.MyController">
<property name="myTemplate" value="classpath:myTemplate.txt"/>
</bean>
And I am trying to load it as a freemarker Template using this code:
private Resource myTemplate;
...
Configuration cfg = new Configuration();
cfg.setClassForTemplateLoading(this.getClass(), "/");
Template tpl = cfg.getTemplate(myResource.getFilename());
But I keep ending up in: java.io.FileNotFoundException: Template classpath:myTemplate.txt not found.
I tried implementing what wassuggested here however it doesn't seem to help.
The only hack I could findso far was to remove the "classpath: prefix from the filename String but I prefer not to do it
Any ideas...?

So what you are saying is that you don't want to remove "class:" from the template name, and according to this question you don't want to teach FreeMarker understanding it via a custom TemplateLoader either. I mean, if you bar these, what else could possibly solve this? I can only advice you to do the last; implement a custom TemplateLoader (either one that just removes the "class:" prefix then delegates to ClassTemplateLoader, or, even better, one that just delegates to a Spring ResourceLoader). That's how you configure FreeMarker to do what you want. It's not something extreme to do, implementing your own TemplateLoader.
Update: It might by useful to know that by default there's a mismatch between the FreeMarker template name syntax and Spring's resource name syntax. According the Spring syntax, you can write "classpath:foo.ftl" or "classpath:/foo.ftl". But FreeMarker assumes that the scheme part always ends with ://, and a lonely : or :/ is nothing special. So all these resource paths will be seen as relative paths, and so the current template directory will be prepended before them before the actual template resolution. To solve this, since FreeMarker 2.3.22, you can use Configuration.setTemplateNameFormat(TemplateNameFormat.DEFAULT_2_4_0) (template_name_format=DEFAULT_2_4_0 in Properties), which does consider : as scheme separator.

Related

openapi documentation how to handle extension in the path

I have URLs like:
/return/{pid}.xml?d1='123'&d2='345'
/return/{pid}.json?d1='123'&d2='345'
the swagger specification calls for:
path:/return/{pid}
....
but how can I map the extension ie
path:/return/{pid}.xml
or
path:/return/{pid}.json
It is a jersey+spring mvc application - so both the URLs are hitting the same controller and only based on the extension the rest framework is going to generate the xml / json output.
I can't ignore the extension from the path ie:
path:/return/{pid}
because the user needs to know that he/she has to provide the file extension as part of the URL. Also I can't use two paths corresponding to xml / json because they are treated the same by the application. In addition it will duplicate things (I am not sure whether there is a fall-through like mechanism just like "case" statements in c++/java "switch" block)
In Swagger specs,You can define the file extensions in the path as below :
/return/{pId}.{fileExtension}
and define the fileExtension in parameters .
also the below is valid (not for your case) :
/return/pid.{fileExtension}

How to handle I18n when texts are not in .properties files but in the jsp page itself

I'm building a multi-languages application with Spring MVC.
So far I handled the multi-languages system with the Spring class ReloadableResourceBundleMessageSource and .properties files. It was easy since texts were very short.
Now, I have to translate the body of the page and I can't rely on .properties files.
I have an Italian version of the page and an english version of the page. My doubt is: how should I handle it?
I thought that after the #Controller return the page name, for example "index", I should have a filter that check the application Locale and then add to the page name a suffix. So, the filter must turn "index" into "it/index" or "en/index".
IS it a good way to solve the issue?
Thank you.
Here's a suggestion with one drawback: I didn't test it with .jsp but .vm. The idea might still work.
As not to break the i18n mechanism put a message key, say parseContent in every language.property file. Now, make a view for every locale and name them, say parse_en_US.vm, parse_de_DE.vm and so on. These files must only contain what you wouldn't want to be in the language.property files.
Example of an entry in messages_en_US.porperties might be parseContent = parse_en_US.vm
An now use #springMessage('parseContent') to get the right view name depending on the present locale. This view you parse as a sub-view and problem solved.
For .vm it looks like this:
#set($view = "#springMessage('parseContent')")
#parse($view)
Same number of .vm files, but no need to invent sth new.

map the url in such a way that it dont show file extension and querystring

i want to show person's name in place of id in URL for example
http://MyWebSite/Doc/Home.aspx?UID=6
to
http://MyWebSite/Doc/Harry
is it possible with url re-writing?
What you really need is to use the VirtualPathProvider
It allows you to control how to map virtual resources.
The request for http://MyWebSite/Doc/Harry would first come to you and if you say the path is virtual (by overriding a FileExists method), the asp.net engine will come to you for the contents of the file (override the GetFile method).
This code project article on Creating Custom Virtual Path Provider should guide you. It implements exactly what you want.
I have solved my problem with System.Web.Routing... taken help from http://www.codeproject.com/Articles/37917/URL-rewriting-using-ASP-NET-routing article

Do *.zcml files get parsed i18n wise?

I have named utilities and would like to mark names for later i18n usage. Is this the right way?
<utility
name="Home"
i18n:attributes="name"
provides=".interfaces..."
factory=".shortcut...." />
The utility's name is not a translatable message id, but an internal technical id. You cannot use it for translation purposes.
If you look at zope.component.zcml you can see the interface for the directive containing:
class IUtilityDirective(IBasicComponentInformation):
"""Register a utility."""
name = zope.schema.TextLine(
title=_("Name"),
description=_("Name of the registration. This is used by"
" application code when locating a utility."),
required=False)
If you look at for example http://wiki.zope.org/zope3/zcml.html it will tell you that an attribute needs to be of type MessageID to be translatable in ZCML.
If you have a ZCML directive with an attribute of type MessageID, all you need to do is to define an i18n:domain for the ZCML file. The ZCML machinery knows what attributes are translatable itself based on them being of the right type. So you don't need any extra markup to note any attributes like you need in TAL.
All that said, if you work inside Plone and use i18ndude to extract messages, it won't extract any messages from ZCML files - simply because there's not a single message being defined in ZCML, that's also actually shown anywhere in the Plone UI.
If you have utilities and want to give them translatable names, give them a title attribute, like:
from zope.i18nmessageid import MessageFactory
_ = MessageFactory('mydomain')
class MyShortCut(object):
title = _('My shortcut')
and use the title attribute in the UI.
You do not want to do that. The name attribute is meant for application use, not end-users, and needs to be stable.
If you translate it, then you'll have to translate all named look-ups through-out your code too!
Titles and descriptions can be translated, using the i18n_domain="domain" marker on the <configure> element.

Access compilation element in web.config [duplicate]

Is there any way to access the <compilation /> tag in a web.config file?
I want to check if the "debug" attribute is set to "true" in the file, but I can't seem to figure out how to do it. I've tried using the WebConfigurationManager, but that doesn't seem to allow me to get to the <compilation /> section.
Update:
I know I could easily just load the file like an XML Document and use XPath, but I was hoping there was already something in the framework that would do this for me. It seems like there would be something since there are already ways to get App Settings and Connection Strings.
I've also tried using the WebConfigurationManager.GetSection() method in a few ways:
WebConfigurationManager.GetSection("compilation")// Name of the tag in the file
WebConfigurationManager.GetSection("CompilationSection") // Name of the class that I'd expect would be returned by this method
WebConfigurationManager.GetSection("system.web") // Parent tag of the 'compilation' tag
All of the above methods return null. I'm assuming there is a way to get to this configuration section since there is a class that already exists ('CompilationSection'), I just can't figure out how to get it.
Use:
using System.Configuration;
using System.Web.Configuration;
...
CompilationSection configSection =
(CompilationSection) ConfigurationManager.GetSection( "system.web/compilation" );
You can then check the configSection.Debug property.
TIP: if you need to know how to get a value from a config file, check the machine.config file in your \Windows\Microsoft.net\Framework\<version>\CONFIG folder. In there you can see how all the configuration section handlers are defined. Once you know the name of the config handler (in this case, CompilationSection), you can look it up in the .Net docs.
The easy way to check if you're running in debug mode is to use the HttpContext.IsDebuggingEnabled property. It gets its answer from the compilation element's debug attribute which is the same thing you're trying to do.
After all, you can always load up the Web.config file into an XmlDocument and use an XPath query to find out!
XmlDocument doc = new XmlDocument();
doc.Load(Server.MapPath("~/Web.config"));
doc.SelectSingleNode("/configuration/system.web/compilation/#debug");
However, I suggest you use the Configuration.GetSection method for solution.
CompilationSection section =
Configuration.GetSection("system.web/compilation") as CompilationSection;
bool debug = section != null && section.Debug;
You can always check debug option on the compiler level by enclosing your code with
#if (DEBUG)
#endif
in case that was the idea...
Try using:
HttpContext.Current.IsDebuggingEnabled
Cant you just load the file up as a regular XML File and use XPath to get the nodes?
Try using the ConfigurationManager.GetSection method.

Resources