Changing locale for thymeleaf utility objects - spring

I want to use #dates or #calendars to get a list of the elapsed months of the current year. This can be achieved using ${#dates.monthName(date)} and a bit of logic, but the name of the months comes in english, and I need it in spanish.
Is there a way to tell thymeleaf to use one locale or another? I've read it uses the standard Date and Calendar from Java, so maybe some sort of application settings for this classes in spring would work?

You've to use the method monthName(Object target, Locale locale) of Thymeleaf DateUtils.
I think something like this should work:
${T(org.thymeleaf.util.DateUtils).monthName(#dates.createNow(), #locale.getDefault())}

Related

Spring Boot : How to httpSession.invalidate() after return statement?

I am working on internationalization in Spring boot. Is it possible to httpSession.invalidate() after returning a page.
As an example
try {
return "finalPage";
}finally {
httpSession.invalidate();
}
What I am trying to do is to show finalPage.html with selected language option first, after clear the session.
But this example first clears the session and then shows the finalPage.html in English not selected Italian. Which means if I choose Italian language for the firstPage.html I expect finalPage.html also in Italian language not default English.
Is it possible the above code example work the way as I wish?
Note: I have achieved my wish by using Thymeleaf tags, I want to do this on the java side if possible.

UI5 - Load proper i18n_xy.properties at onInit and later on manually

We have the requirement, that we shall host an SAPUI5 application inside a java-application's host, which our vendor offered to us by implementing and exposing jxbrowser.
This vendor's java application offers an api, which can be accessed from within our SAPUI5 application.
This java api offers also an environment (or config-settings), where, amongst a rich set of settings, also a user language can be obtained.
And this language is neither a sap-logon language param nor is it guaranteed to be always the language which is set up in the "jx-browser" ( if possible at all, like in all real browsers ), and it uses the standard i18n _xy_AB acronym's naming style.
And I want to load the proper i18n_xy.properties at onInit of my first view and set them in the code.
We do have currently 4 of them ( _de,_it,_fr ), and the fallback is also present.
I am a little idiot, because I found some quick n dirty code, but this was about one month ago and I simply forgot the link and all of that. So now I need to ask( and maybe even for a best practice solution to this...)
So, additionally, another (my personal) requirement is, that, once I retrieve the right i18n file, I want to set it, in a way, that, whenever later on, I would use
info = this.getView().getModel("i18n").getResourceBundle().getText("obfuscated");
I always obtain the right text in the right language.
What I think of, is: Load the proper file ( according to the environment settings from the api ) in onInit, set this i18n as the proper one for the rest of the application's runtime and use a easy name for it, which will then be referred to as, maybe this:
info = this.getView().getModel("i18n_loaded").getResourceBundle().getText("obfuscated");
Is this possible, is this the right way, and , if not, which one is, according to some kind of guidelines, the best practice for this scenario ?
You can pass the parameter in the url:
sap-ui-language=en
Or set the default language in your JavaScript code:
sap.ui.getCore().getConfiguration().setLanguage("en-US");
I was not completely aware, that the determination of the used locale also works the other way around.
Meaning, if the ressource bundle contains e.g. 4 i18's,called i18_en, i18_it, i18_de, i18_fr, and the either the app is set up by
sap.ui.getCore().getConfiguration().setLanguage("en-US");
or the url-param, this not only means, that:
All ui-elements will be translated propery, once the locale's acronym is properly spotted
ALSO this is automatically replaced by the proper spotted ressource file and the translated text is retrieved properly....
info = this.getView().getModel("i18n").getResourceBundle().getText("obfuscated");
I was aware of how this fallback determination of a locale works, but I was not aware that it works also the other way around.
I close my question and i do not care about any rewards.

Vaadin & Spring Boot - Alternative translations within ValidationMessages.properties are not picked up

I tried to use BeanFieldGroup<Entity> in Vaadin Spring Boot, with javax.validator and Hibernate validators.
#NotBlank(message = "{may.not.null}")
#Column(name = "name", unique = true)
private String name;
and I created two files: ValidationMessages_en.properties:
may.not.null=not null
and ValidationMessages_fr.properties:
may.not.null=non null
But even when I change the language to French, the validator message is still from ValidationMessages_en.properties.
Have any of you any idea about this, please?
The BeanFieldGroup creates the BeanValidator with the locale, which is set to the component under validation. Your question does not mention how you create the text field for the name property, but let's assume that you create it this way:
TextField nameTextField = new TextField("Name");
The important factor here is to make sure that the nameTextField has correct locale before you bind the properties with BeanFieldGroup (you can check the locale with nameTextField.getLocale()).
So, try to configure your TextField to use the session locale like this:
nameTextField.setLocale(UI.getCurrent().getLocale());
This piece of code takes the locale from the request ("Accept-Language" request header) and sets it to the field -> the BeanFieldGroup will then create BeanValidators with the correct locale and the validation messages are localized (this happens in BeanFieldGroup#configureField).
However use this code only to check that the problem is really only in that your text field does not have correct Locale. It really does not mean that you have to set the Locale for each and every field out there... That's because in Vaadin (at least in Vaadin 7) the session (request based) Locale should be inherited by component from the parent. So if you add TextField to the Layout, then the TextField inherits the locale of the Layout, the Layout inherits it from the View and so on (all the way up to UI.getCurrent().getLocale() - so check that you have desired locale there). Since the inheritance happens during addComponent() call, it's my guess, that, maybe, in your case, it would be enough to call the addComponent() method (where you are adding the TextField to the layout) before you actually use the BeanFieldGroup binding.
More info about your problem here: Remember to set the Locale
Note: I tried to code your issue right now, I faced the same problem as you had and resolved it by moving the addComponent() call before the BeanFieldGroup.

Spring MVC: how to get case-insensitive ordering from Pageable

I am trying to support case-insensitive ordering in my Spring MVC app when users click on the column headings on my web page. When the page is rendered a Thymeleaf extension creates an anchor and the href is the current URL with some parameters supported by Pageable: i.e. page, size and sort.
The sort=propertyName,ASC format works fine, but I can't find out how to say that the sort should be case-insensitive from the URL. I can do it in code easily enough but the standard Pageable support doesn't seem to support it.
After some debugging it appears that the standard framework org.springframework.data.web.SortHandlerMethodArgumentResolver just doesn't have any support for org.springframework.data.domain.Sort.Order.ignoreCase.
I'm somewhat bemused about this, and am wondering if there's a good reason why?
I can look into creating my own SortHandlerMethodArgumentResolver class, and make it parse ASCI|DESCI (to mean case-insensitive), and ASCS|DESCS (to mean case-sensitive) and produce the appropriate Sort object, but this strikes me as quite a bit of work and a serious "code smell".
I can't be the first person to stumble across this. Does anyone have any advice?
I think the only option is to implement your custom SortHandlerMethodArgumentResolver. The documentation has brief guideline for this http://docs.spring.io/spring-data/data-commons/docs/1.6.1.RELEASE/reference/html/repositories.html
To customize this behavior extend either SpringDataWebConfiguration or
the HATEOAS-enabled equivalent and override the pageableResolver() or
sortResolver() methods and import your customized configuration file
instead of using the #Enable-annotation.
For the format I would make it a comma-separated string of 3 elements: field name, direction, ignoreCase flag. Something like this:
sort=name,ASC,ignore
The last element is optional so it's possible to have:
sort=name,ASC
which would mean that ignoreCase is false.
Also it should be possible to specify only field name like:
sort=name
which would mean the default direction of ASC and ignoreCase is false.
The only issue is if you want to pass ignoreCase flag you must pass the direction which should not be a big problem I think.
Hope this helps!
Btw here is a JIRA item for this improvement https://jira.spring.io/browse/DATACMNS-658 (Extend SortHandlerMethodArgument resolver to be able to detect the request for ignore-case)
If somebody is using Spring Data Commons 2.3 RC1 or later and looking for query params, use following. (Ignore case in sorting is available out of the box in Spring Data Commons 2.3 RC1 and later)
sort=name,ASC,ignorecase

How to display the current date & time in the Freemarker template section of smooks?

I am able to display the contents of my incoming XML file using smooks in the freemarker template, but I want to add Current Date & time of my local system to identify the execution of my program.
<ftl:freemarker applyOnElement="CreditCard">
<ftl:template><!-- <BalanceInquiryRequest>
<TransactionId>${BalanceInquiryRequest.TransactionId}</<TransactionId>
<ConfigurationId>${BalanceInquiryRequest.ConfigurationId}</ConfigurationId>
<CardNumberr>${.vars["GiftCard"].CardNumber}</CardNumberr>
<ExpirationDate>${.vars["GiftCard"].ExpirationDate}</ExpirationDate>
<SecurityCode>${.vars["GiftCard"].SecurityCode}</SecurityCode>
*****************************
Here I want to display the current Date & time
</BalanceInquiryRequest>
--></ftl:template>
</ftl:freemarker>
Can you tell me how can I add current date & time in the XML without having an entry in the incoming XML.
use .now, they introduced it some time ago, no need for java
There seems to be an answer here. The short answer, you need to pass in Java.
You cannot do it since XML like Freemarker are template engines, not objects. You have to pass it into the java object as new Date();
You could write a short groovy script in the Smooks configuration file to populate a bean in the beancontext with today's date. Then the freemarker script could use the value from that bean.
Edit: You can read more about Groovy and Smooks here: http://www.smooks.org/mediawiki/index.php?title=V1.3:Smooks_v1.3_User_Guide#Groovy_Scripting
You probably want to use methods from http://www.milyn.org/javadoc/v1.2/smooks-cartridges/javabean/org/milyn/javabean/repository/BeanRepository.html and do something similar to:
<g:groovy executeOnElement="xxx">
<g:script>
<!--
addBean("date", new Date());
-->
</g:script>
</g:groovy>
You should then be able to access the "date" bean in your freemarker.
You can do it without .now and you don't have to pass in new Date.
I'm having to work with old freemarker at the moment and did this instead..
<#assign dateNow = Static["java.util.Calendar"].getInstance().getTime()?datetime />

Resources