How freemarker custom function compile with normal order? - freemarker

i tried to build a web app with freemarker.
when i define and used a custom function like (fetchVarFromDB is a custom function):
1: <#assign a=1 />
2: xxx(some crud ops which update the db values)
3: <#assign b=fetchVarFromDB() />
line 3 always be compile first. But i need it executed order by line 1,2,3,
because line 2 updated some db values.
how could i do that?

Related

using <#include> resoults in error: Can't find resource

I am implementing a freemarker code in an environment that stores the templates in an database.
for example
${bundle.key}
will display the value of the row with row_id = 'key'
However when I use include directive something doesn't work.
I have a template with a key GenF as follows
<#function PriceFormat Number>
<#return Number?string['0.0000']>
</#function>
if i run
${GenF.PriceFormat(1.568)}
I get the output
1.5680
as expected.
but when i run
<#include bundle.GenF>
${PriceFormat(1.568)}
I receive an error message:
Can't find resource for bundle ...structures.shared.localization.bl.MultiResourceBundle, key
do I use the include directive wrong, or is something was not defined correctly in the Data model by our programmers?
#include expects the name
(path, "file" name) of a template, not the template content itself. See: https://freemarker.apache.org/docs/ref_directive_include.html
What you seem to want is <#bundle.GenF?interpret />. Though note that the parsed template won't be cached that way, unlike when you invoke a template with #include. For #include to be able to resolve "bundle.GenF" as template name (or rather something like "bundle:/GenF", but it's up to you), you have to use a custom TemplateLoader (see Configuration.setTemplateLoader).
As far as you only need this for defining custom number formats, you may also want to consider using custom number formats (https://freemarker.apache.org/docs/pgui_config_custom_formats.html), like ${1.538?string.#bundle_GenF}.

How to escape '-' in SpEL in thymeleaf

In my Spring Controller I set following to my model attribute:
model.addAttribute("abc-def", "Hello World");
In my thymeleaf html I want to read the value of abc-def.
<th:block th:text="${abc-def}"></th:block>
But I get the error:
The operator 'SUBTRACT' is not supported between objects of type 'null' and 'null'
Its clear because - is an arithmetic operator. Is there a way to escape - for reading out the model value?
My advice would be: don't use variables names with dashes in them. (Would you try to define a variable int abc-def = 5; in java?)
In any case, this seems to work if you have to use it:
<th:block th:text="${#request.getAttribute('abc-def')}" />
Thymeleaf 2
Per the Expression Basic Objects section of the documentation (with more details in Appendix A), the context variables are in a #vars object. So, you can access variables with something like this:
<th:block th:text="${#vars.get('abc-def')}" />
Thymeleaf 3
As Metroids commented this all changes in Thymeleaf 3. It combines the #ctx and #vars objects, so you need to use the Context's getVariable method:
<th:block th:text="${#ctx.getVariable('abc-def')}" />
But this isn't the best plan
While certainly these will "work", having variables with punctuation in them is a bit unusual, and may confuse the next programmer to see your code. I wouldn't do it unless I had a really good reason to use that name.

camel:when on header value using blueprint

I have camel routes that make rest calls based on header values.
I had been using xpath to read values from xml and set them as the header and used xpath in a block as so:
<camel:setHeader headerName="clear">
<xpath>/TicketInfo/TicketData/Clear/text()</xpath>
</camel:setHeader>
<camel:choice>
<camel:when>
<camel:xpath>$clear='CLEARED'</camel:xpath>
<camel:doTry>
...
but now I am forced to use json so xpath will not work. I now have:
<camel:setHeader headerName="clear">
<camel:jsonpath>$.ticket.Type</camel:jsonpath>
</camel:setHeader>
<camel:choice>
<camel:when>
<camel:xpath>$clear='CLEARED'</camel:xpath>
<camel:doTry>
...
but obviously the <camel:xpath>$clear='CLEARED'</camel:xpath> part won't work anymore. Is there another way I can check the value of $clear header to restrict when the <camel:doTry> and following execute?
Try the simple language :
<camel:when>
<camel:simple>${in.header.clear} == 'CLEARED'</camel:simple>
<camel:doTry>
See this documentation

Automatic Step Generation in cucumber javascript using javascript

I am using javascript for cucumber javascript for automation.My concern is can i generate .js file for step definitions automatically? as of now am copy pasting them(steps) from command line window so can I skip it and directly generate the step file?
Two Suggestions:
1.
You can create a new gherkin file, and run it with cucumber.js, it will generate JavaScript stub automatically for you. For example:
"cucumber-js math.feature"
It will output something like:
1) Scenario: easy maths - math.feature:7
Step: Given a variable set to 1 - math.feature:8
Message:
Undefined. Implement with the following snippet:
this.Given(/^a variable set to (\d+)$/, function (arg1, callback) {
// Write code here that turns the phrase above into concrete actions
callback(null, 'pending');
});
It has the parameter automatically generated based on your tests. You can then copy the snippet into your code file.
2.
If you are using Windows 10, you can also try a BDD development tool CukeTest, and it provide some convenient features like code generation from step text, or navigate between code and steps etc.
You can use 'Live Template'/'Code snippets' in your IDE. It's the best way to improve performace.
https://www.jetbrains.com/help/idea/creating-code-constructs-by-live-templates.html
If you use VC Code then you can use extension Cucumber (Gherkin) Syntax and Snippets:
https://marketplace.visualstudio.com/items?itemName=stevejpurves.cucumber

SoapUI XPath assertion with wildcards

Is there a way to use a wildcard inside an assertion in a XPath test with SoapUI?
I took a look at SoapUI's documentation and they say you can do something like this
<path1>
<path2>*</path2>
</path1>
I checked the 'Allow Wildcards' checkbox.
My question is : I want to assert my date starts with 2012-08-22 but i dont care about the minutes and seconds. I guess my the expression should be something like 2012-08-22* but it doesn't work.
What you are doing sounds like it should work. Here is a quick example i cooked up using a rest service from http://www.geonames.org/export/web-services.html#timezone. I'm using the demo they have supplied
http://api.geonames.org/timezone?lat=47.01&lng=10.2&username=demo
output is
<geonames>
<timezone tzversion="tzdata2012c">
<countryCode>AT</countryCode>
<countryName>Austria</countryName>
<lat>47.01</lat>
<lng>10.2</lng>
<timezoneId>Europe/Vienna</timezoneId>
<dstOffset>2.0</dstOffset>
<gmtOffset>1.0</gmtOffset>
<rawOffset>1.0</rawOffset>
<time>2012-07-25 04:39</time>
<sunrise>2012-07-25 05:50</sunrise>
<sunset>2012-07-25 21:00</sunset>
</timezone>
</geonames>
If you do an xpath match on the result and use the select from current button you get
//geonames/timezone/time
2012-07-25 04:39
If you update this to
//geonames/timezone/time
2012-07-25*
this will work fine and when updating the rest request with a new lat and lng the assertion will still pass since it is not checking the time. If this doesn't help, please supply your full assertion and maybe i could help more.
*note: for soap requests, make sure to declare the namespace and then use the proper format
//ns1:message
It will be sort of a pain, but here is what you can do:
1) Figure out an Xpath 'base' using the assertion tab (sounds like you are here already). I used this public site to test against: http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl
I used the CornerPoints method with 'hawaii' as the single param.
I created this 'base' xpath:
declare namespace ns1='http://graphical.weather.gov/xml/DWMLgen/wsdl/ndfdXML.wsdl';
declare namespace SOAP-ENC='http://schemas.xmlsoap.org/soap/encoding/';
declare namespace SOAP-ENV='http://schemas.xmlsoap.org/soap/envelope/';
/SOAP-ENV:Envelope/SOAP-ENV:Body/ns1:CornerPointsResponse/listLatLonOut
(it will write the declare statements for you if you click declare)
(which you can test out in the assertions window)
2) Create a Properties step
3) Create a Property transfer step
4) Create a groovy script
5) add a property... i called mine misc
6) add a transfer step
* transfer from the CornerPoints - Request 1 --- Response
* paste the Xpath stuff in the box under the 'transfer from'
* Transfer to your property
(You can test with the little play button)
7) Add something like this to your groovy script:
def x = context.expand( '${Properties#misc}' )
def parts = x.tokenize(',')
for (def part in parts)
{
log.info(part)
if (part.startsWith("-153"))
log.info("good")
}
In the groovy step you can do anything you need to get at your (partial) data. The sample code I added gets lat/lons out of a long line wrapped in CDATA and then checks for just the starting part of some of the data.. just an example.
Remember that you can use groovy and java string methods:
http://groovy.codehaus.org/groovy-jdk/java/lang/String.html
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/String.html
More groovy tips:
http://www.soapui.org/Scripting-Properties/tips-a-tricks.html

Resources