I am working on freemarker template using Smooks for EDI Translations
I just perform the MD5 hashing of a string in 16 digit hexadecimal format..
I am not able to find the relevant syntax for implementing Md5 hashing in Freemarker logic
when trying to import
#import java.security.MessageDigest
in freemarker in smooks-config.xml file, it throws an error
Caused by: freemarker.template.TemplateNotFoundException: Template not found for name "java.security.MessageDigest"
FreeMarker templates can only #import other FreeMarker templates (see the documentation). Also, generally, you aren't supposed to calculate such things in FreeMarker templates. You should pass the already calculated hex string to the template.
But, if you can't do the above, then you can write a small utility object in Java that has the required methods, and then add that to the FreeMarker data-model, or to the FreeMarker configuration as "shared variable". However, I don't know if Smooks is configurable enough to do that.
If Smooks doesn't let you configure FreeMarker much (as needed above), you can write a TemplateMethodModel implementation in Java that calculates the value you need, and then create an instance of that inside your template as <#assign md5 = 'com.example.MyMD5Method'?new()>, and then later you can do things like ${md5(something)} in FreeMarker. (Of course, this requires that you can add a new class to your application.)
If the Md5 hashing can be performed by a static method of a given class and you really cannot do the job before the template is processed... you can expose this class to the template.
I'm not familiar with Smooks, but basically you need tell Smooks to inject a modified FreemarkerManager which has an overriden method populateContext
public class MyFreemarkerManager extends FreemarkerManager {
#Override
protected void populateContext(ScopesHashModel model, ValueStack stack, Object action, HttpServletRequest request, HttpServletResponse response) {
super.populateContext(model, stack, action, request, response);
BeansWrapper beansWrapper = new BeansWrapperBuilder(Configuration.VERSION_2_3_24).build();
TemplateHashModel staticModels = beansWrapper.getStaticModels();
TemplateHashModel utils = (TemplateHashModel)staticModels.get("path.to.your.class.Utils");
model.put("Utils", utils);
}
}
Now all your templates have a direct access to the static methods of the Utils class
${Utils.hashMd5(s)}
Related
We are using velocity to parse our templates.
Velocity developer guide suggests to create a new VelocityContext for every parsing
But what about the VelocityEngine and the RuntimeInstances?
Can we reuse them or is it better to create new instances every call ? Will the new instances of VelocityEngine cause memory leaks ?
public String parse(String templateStr, Map<String, String> params) {
StringWriter writer = new StringWriter();
try {
VelocityEngine velocityEngine = new VelocityEngine();
velocityEngine.init();
RuntimeServices rs = RuntimeSingleton.getRuntimeServices();
StringReader sr = new StringReader(templateStr);
SimpleNode sn = rs.parse(sr, "template");
Template t = new Template();
t.setRuntimeServices(rs);
t.setData(sn);
t.initDocument();
VelocityContext context = new VelocityContext();
if (params != null && !params.isEmpty()) {
for (Entry<String, String> entry : params.entrySet()) {
context.put(entry.getKey(), entry.getValue());
}
}
t.merge(context, writer);
} catch (Exception e) {
LOGGER.error("Exception in velocity parsing", e);
}
return writer.toString();
}
Velocity allows you to use Singleton model
Velocity.setProperty(Velocity.RUNTIME_LOG_NAME, "mylog");
Velocity.init();
Template t = Velocity.getTemplate("foo.vm");
Developers have two options for using the Velocity engine, the singleton model and the separate instance model. The same core Velocity code is used for both approaches, which are provided to make Velocity easier to integrate into your Java application.
Basically, instead of VelocityEngine, you can use Velocity class:
This class provides a separate new-able instance of the Velocity template engine. The alternative model for use is using the Velocity class which employs the singleton model.
RuntimeInstance is an internal class you don't have to deal with.
VelocityEngine, as well as the singleton class Velocity (which relies on VelocityEngine), are re-entrant (as well as their associated template resource loaders). It means that they can safely be used in a multi-threaded environment.
Each time you instantiate a VelocityEngine, you'll need to call init() once on it. Reusing a previous VelocityEngine instance avoids the need for additional init() calls.
But the key benefit in reusing a VelocityEngine instance is to make use of automatic template parsing and caching via its resource loaders. In the code in your question, you're manually instantiating Template objects and loading them with data from strings. A cleaner way is to configure your VelocityEngine to support a "string resource loader", then store each string containing a template body within a StringResourceRepository associated with your VelocityEngine instance. This is all demonstrated for Velocity 2.1 at this StackOverflow answer.
A few notes in addition:
Velocity will take care of parsing your templates automatically with
the approach shown in the link, above. No need to manually parse or call initDocument() on a Template.
With this approach Velocity will take care of caching your templates (in parsed form)
automatically if you've configured your string resource loader (in
your VelocityEngine instance) with caching enabled.
The above two points will allow your code to be simpler and faster. You can further simplify the code: instead of calling yourVelocityEngineInstance.getTemplate() and then merge(), you can call yourVelocityEngineInstance.mergeTemplate().
When adding a template to a StringResourceRepository via a call to yourRepo.putStringResource(), you specify a template name as well as the body of the template. If there is no obvious name to use you can write an MD5 hashing function to quickly generate an MD5 hash string of the template body and use that as a unique name (got this tip from another Velocity user). If the template body ever changes that would generate a distinct name. There is a corresponding removeStringResource() method to delete templates from the string resource repository.
Once a template is placed in the string resource repository Velocity can locate it "magically" by name. You can call yourVelocityEngineInstance.resourceExists("YourTemplateName") to see if a given template exists in the repository or not.
I do not know the performance cost of instantiating and initializing a
VelocityEngine, a RuntimeInstance or a VelocityContext. Until the Velocity documentation provides clearer guidance on optimizing performance, you'll have to do your own performance testing to find out.
I want to generate one HTML file form a String content.
But I do not want to hard code HTML tags (like <html>, <body>, <tr>, <td> etc.) in the Java class. In the same time, I also do not want to use any third party library for it.
It is a simple Java project (there is no web project flavor).
In my mind, I am thinking of using a properties file to configure all HTML tags and use those properties in my Java class.
If anyone has any other way to do this, please suggest me through a simple example.
I've been experimenting along these lines for one of my projects (producing an image of a receipt, going through HTML/CSS because wkhtmltopdf can render it as a PNG). I think you will find that trying to abstract your string generator to handle potential future output of CSV, XML, etc. will over-complicate your method. I have objects right now that I deal with via JSON, XML, and HTML, and they all require different approaches. For JSON, I rely on Spring's conversion. For XML, I use JAXB. For HTML, I have been doing what a couple of people mentioned in comments with templates.
e.g.
String template = "<html><head/><body><h1>Hello %s</h1></body></html>";
System.out.println(String.format(template, "World");
As also suggested in the comments, you could load that template string from a file, but this will become complicated very quickly, such as if you have objects within your first object which need to generate their own HTML:
public Class Container{
private String name;
private OtherClass other;
public convertToHtml(){
String template = "<html><head/><body><h1>Hello %s. Other: %s</h1></body></html>";
return String.format(template, name, other.convertToHtml());
}
}
public Class OtherClass{
private String stuff;
public convertToHtml(){
String template = "<span>%s</span>";
return String.format(template, stuff);
}
}
Freemarker is used as the default template engine in the ninja web framework. The framework assigns some default values to a template which are globaly available when using the ninja web framework. I have created an extension for the template which does enbales CSRF-Protection. The extension offers a function which can be used in a template, e.g.
${foo(bar)}
At the moment the function needs to be called with specific parameters, which is not very intuitiv. Using a macro I could simplify this call to
#{foo}
and the user doesn't need to worry about passing the correct (e.g. "bar") parameter. But to make this available in the ninja web framework I have to define a macro programmatically. Is that possible?
UPDATE
Sorry for the confusion. Meant <#foo/> instead of #{foo} ...
Looking at the Freemarker documentation I maybe can make more clear what I want to achieve: http://freemarker.org/docs/ref_directive_macro.html
Like I explained above I am passing a custom function to the template, enabling me to call
${foo("bar")}
What I want to do, is call this via a macro like
#<myMacro/>
But the defined macro like
<#macro myMacro>
${foo("bar")}
</#macro>
should not be defined in the template but programmatically. Hope that makes it more clear.
UPDATE2 / SOLUTION
I ended up using the recommended TemplateDirectiveModel.
public class TemplateEngineFreemarkerAuthenticityTokenDirective implements TemplateDirectiveModel {
private String authenticityToken;
public TemplateEngineFreemarkerAuthenticityTokenDirective(Context context) {
this.authenticityToken = context.getSession().getAuthenticityToken();
}
#Override
public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException {
if (!params.isEmpty()) {
throw new TemplateException("This directive doesn't allow parameters.", env);
}
if (loopVars.length != 0) {
throw new TemplateException("This directive doesn't allow loop variables.", env);
}
Writer out = env.getOut();
out.append(this.authenticityToken);
}
}
FreeMarker macro invocations doesn't look like #{...}. Is that some kind of Ninja-specific extension?
Anyway, if you know that there's a bar in the data-model, then your method can get it like Environment.getCurrentEnvironment().getDataModel().get("bar"), so it need not be passed in.
Also, it's maybe useful to know that FTL has two kind of "subroutines", the function-like ones, and the directive-like ones. Both can be implement both in FTL (#function, #macro) and in Java (plain Java methods, TemplateMethodModelEx, TemplateDirectiveModel). The real difference is that the function-like ones are for calculating values, and the directive-like ones are for printing values directly to the output (hence bypassing auto-escaping) and for side-effects. But all of these can reach the Environment, so there's no difference there.
You can call a macro "dynamically". Let's say you had a macro:
<#macro myMacro>
${foo("bar")}
</#macro>
You can call it like this:
<#myMacro />
OR
<#.vars["myMacro"] />
So then you can do...
<#assign someVar = "myMacro" />
<#.vars[someVar] />
I am using cucumber-java in groovy code. I prefer cucumber-java to cucumber-groovy because I can run the tests like plain old good JUnit tests. However, the step definition templates spitted out by cucumber are in java style. Instead, I would like to have a groovy style. For example, in java style, you will get something like
#When("^an HTTP GET request is sent to obtain config.xml of \"([^\"]*)\"$")
public void an_HTTP_GET_request_is_sent_to_obtain_config_xml_of(String arg1) throws Throwable {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
Since I am using groovy, I would like to get something like
#When(/^an HTTP GET request is sent to obtain config.xml of "([^"]*)"$/)
void 'an HTTP GET request is sent to obtain config.xml of'(String arg1) {
// Express the Regexp above with the code you wish you had
throw new PendingException();
}
I am thinking to implement such a feature. Basically, my idea is to add a new field, maybe called templateLanguage, in cucumber.api.CucumberOptions. When this new field is equal to groovy, then the groovy-style templates will be spitted. This will probably involve an if statement in cucumber.runtime.java.JavaSnippet.template(), such as
if( runtimeOptions.getTemplateLanguage().toLowerCase().equals('groovy') ) {...}
However, my question is: how can I get a reference of the runtimeOptions that is passed in like
#CucumberOptions(
format = ["pretty", "html:build/cucumber"],
features="src/test/resources/cucumber_features/api/job_view.feature",
glue=['com.yahoo.adcd.jenkins.tests.smoke.api.cucumber.job.view'],
strict = true
)
Thank you very much!
In a case like this, you would need to write your own boot class since there is no dependency injection for RuntimeOptions. A good starting location is to look at cucumber.api.cli.Main. You would need to create your own class that extends RuntimeOptions, then add in your logic there.
This solution, however, will not allow you run the app using the CucumberOptions annotation anymore. If you do prefer using the annotation though, you would need to also implement your own custom annotation and override the RuntimeOptionsFactory to use your annotation, and then use that factory in your new main class to create the runtime dynamically.
I have a customized JSP tag library with a Java class (extending TagSupport) that generates the output for my web application. It has some parameters that are formed into HTML code using a StringBuilder.
Now the generated HTML is becoming more complex and hard to handle with calls of StringBuilder.append, so I'd like to replace the code generation with a Freemarker template.
I already found out that I could use a generic Struts component tag instead, because the Struts tags already use Freemarker template files, so I could write a tag like:
<s:component template="/components/myStruct.ftl">
<s:param name="myParam" value="%{'myParam'}" />
</s:component>
Then writing the specified template file myStruct.ftl would probably solve my problem. I actually did not try if Struts really finds and uses that file correctly, but I optimistically expect it to work.
My question is, if it's also possible to retain the current code with the customized tag
<my:struct param="myParam" />
and only change the Java class linked to that tag.
I've found code that reads a Freemarker template:
Configuration config = FreemarkerManager.getInstance().getConfiguration(pageContext.getServletContext());
config.setServletContextForTemplateLoading(pageContext.getServletContext(), "/components");
Template templ = config.getTemplate("myStruct.ftl");
templ.process(params, pageContext.getOut());
but it seems very circuitously to me and I wondered what would be the "standard" way to do it. Additionally it seemed that you cannot use tags from the Struts tag library in a template used like this. (I ran into an ArrayIndexOutOfBoundException, caused by Sitemesh... I did not analyze it yet.)
My intention was to keep the Java class as some kind of wrapper around the Struts component tag. Maybe somthing like:
OgnlValueStack stack = TagUtils.getStack(pageContext);
Component c = new Component(stack);
c.addParameter("param", param);
But I don't know how to continue this code stub. It may be crap anyway.
Is there an easy/"standard" way to do this or do I simply have to get rid of the customized tag?
Thanks in advance.
A friend of mine sent me this link:
http://cppoon.wordpress.com/2013/02/27/how-to-create-a-struts-2-component-with-freemarker/
This is what I was looking for. The gist is to change the customized tag to not extend TagSupportbut AbstractUITag which makes it a Struts tag instead of a JSP tag, roughly speaking.
This enables the automatic linkage (by name and path conventions) to my Freemarker template. I basically followed the instructions on that page. I only added the methods that are abstract in the super class, so they had to be implemented.
IMO the site lacks of a description of how the UI bean class is linked to the tag class. But as the IDE forces you to implement the getBean method inside the tag class, you quickly get to this code (using the classes described on that site):
#Override
public Component getBean(OgnlValueStack stack, HttpServletRequest request, HttpServletResponse response)
{
Pagination pagination = new Pagination(stack, request, response);
pagination.setList(list);
return pagination;
}
This might not be completely correct for the recent Struts, but it worked for the ancient version I've got to use.
Thanks again to the guy who sent me the link :)