How can I access an central ResourceBundle in Wicket - java

The Internationalization of Wicket is realized with many little Properties-Files in the same folders like there html-Files.
My architekture ist one Properties-File in the webapp-Folder or an other unique Folder.
My favorite Example:
src/java/main/net/kog/WicketApplikation.java:
getResourceSettings().getResourceFinders().add(
new WebApplicationPath(getServletContext(), "resource"));
BundleStringResourceLoader bundle = new BundleStringResourceLoader("text.properties");
getResourceSettings().getStringResourceLoaders().add(bundle);
// Test
String str = bundle.loadStringResource(net.kog.resource.Text.class, "login.noscript", Locale.getDefault(), null, null);
System.out.println(str);
Markup:
<div wicket:id="login.noscript" id="js"/>
But whereever I locate the File text.properties the ResourceBundle not found, no String was returned.
tried Locations:
src/main/webapp
src/main/webapp/resource
src/main/webapp/WEB-INF/resource
src/main/webapp/WEB-INF/classes/resource
src/main/resources
src/main/resources/resource
src/main/resources/net/kog/resource

Please read http://wicket.apache.org/guide/guide/i18n.html for more information how to split or combine the resource bundles in your application.

Solution:
First, the answer of martin-g has given the right direktion. The properties-File have to be the same name like the Application-class ("WicketApplication.properties").
Second, very useful was to change the debuglevel in Wicket (src\main\resources\log4j2.xml) from LEVEL.INFO to LEVEL.DEBUG. There was a many Information about the URL (Path) which Wicket has tried to loaded.
Third, I make the way to access my properties-File shorter, because I delete IsoPropertiesFilePropertiesLoader (ISO-8859 formated Properties-Files) and XmlFilePropertiesLoader in net.kog.WicketApplication.init(). Code:
List<IPropertiesLoader> propertiesLoader =
((PropertiesFactory)getResourceSettings().getPropertiesFactory()).getPropertiesLoaders();
getResourceSettings().getPropertiesFactory().clearCache();
propertiesLoader.clear();
propertiesLoader.add(new UtfPropertiesFilePropertiesLoader("properties", "utf-8"));
The full path of my UTF-8 properties-File is src/main/webapp/net/kog/WicketApplication.properties

Related

Thymeleaf context URL processing - how to add language code to context-relative URLs (Spring + Thymeleaf)

I have written request filter and locale resolver for getting language code from URL. (for example: DOMAIN/en/, DOMAIN/cs/)
However, I don't know how to change programmatically the context path that Thymeleaf uses for its context-relative URLs (#{/css/main.css}).
For example, if on page with address "DOMAIN/en/test/" is following code
<a th:href="#{/test2/}">TEST 2</a>
it points at
DOMAIN/test2/
instead of
DOMAIN/en/test2/
I thought it would be good to create some filter that edits the URL before it goes to Thymeleaf templates, but I don't have any idea how.
Do you have any ideas how to solve it?
I've found solution that suits my expectations.
I just wanted to insert language code after context path (example.com/CONTEXT_PATH/CONTROLLER -> example.com/CONTEXT_PATH/LANGUAGE_CODE/CONTROLLER) for Thymeleaf templates, so I can still use Thymeleaf's url expression #{/controller}.
I have url filter that removes language code and adds it to request's attributes, so I have just edited the response's encodeURL method and it works as I wanted:
getServletContext().getRequestDispatcher(newUrl).forward(request, new HttpServletResponseWrapper(response) {
#Override
public String encodeURL(String url) {
String contextPath = getServletContext().getContextPath();
if (url.startsWith(contextPath))
url = new StringBuilder(url).insert(contextPath.length(), "/" + getLocale().getLanguage()).toString();
return super.encodeURL(url);
}
});
Anyway, thanks for your answers! :)
One solution is to put urls in message resource files:
<a th:href="#{#{orders.details.localized_url}(id=${order.id})}">
as described in: http://www.thymeleaf.org/doc/articles/standardurlsyntax.html
Or return appropriate template view for example:
#RequestMapping("/localized/**")
public String getTemplateView(HttpServletRequest request) {
String path = request.getRequestURI();
//path = /localized/en/mypage
return mypage_en.html;// or relative location in the configured folder
}
I like the first one better

How to change slf4j log into html link

I have java code as:
final URI myUri = new URIBuilder()
.setScheme(azkabanHostProtocol)
.setHost(azkabanHost + ":" + azkabanPort)
.setPath("/executor")
.setParameter("execid", executionID).build();
logger.info(myUri.toString());
I want to display myURI in form of an url/html link into Azkaban's logs so that by clicking on the url it is opened. I am using log4j for logging.
You may create your own Layout class extending HTMLLayout .
Then override the format method to suit your needs.
The actual implementation has the following lines, that you may want to replace :
sbuf.append(Transform.escapeTags(event.getRenderedMessage()));
See that all tags in the message String, will be escaped by default.
Your version could be based on a kind of marker, say String mark = "[LINK]"; for instance
if(event.getRenderedMessage().startsWith(mark)){
String uri = event.getRenderedMessage().substring(mark.length());
String link = "" + uri + "";
sbuf.append(link);
}
else
sbuf.append(Transform.escapeTags(event.getRenderedMessage()));
And you would call the logger this way :
logger.info(mark + myUri.toString());
The following topic will help you use a custom HTMLLayout : how to change htmllayout in log4j2
Here is the source code for the default HTMLLayout, as a starter.
How do you view the Azkaban log files? If they are just raw text files being viewed with a vanilla text editor then there is no way to accomplish what you want. If you are viewing them in a smarter UI then you need to format them according to what that UI requires.
In short, the answer to your question is completely driven by whatever tool you are using to view the logs.

Access to MessageResources

What's the analogous of
Resources.getMessage(request,"key");
(it's in org.apache.struts.validator package)?
I need to take the right string according to the language in use and put that string in an array.
These strings have a variable part. For example:
The field %s is required
I want to take the The field and is required from the MessageResources
EDIT
I've used
ResourceBundle myResources = ResourceBundle.getBundle("MessageResources");
String msg = MessageFormat.format(myResources.getString("errors.required"),
new Object[] { title });
It works, but only with the default language
You can use a resource bundle for this in idiomatic Java. The bundles are properties files, and they are named according to their locale's.
Here is a link to ResourceBundle in the Java API documentation.
http://docs.oracle.com/javase/7/docs/api/java/util/ResourceBundle.html
Let me know if you need any more info.

Do resource bundles in Java support runtime string substitution?

Can you do the following with a Java ResourceBundle?
In the properties file...
example.dynamicresource=You currently have {0} accounts.
At runtime...
int accountAcount = 3;
bundle.get("example.dynamicresource",accountCount,param2,...);
To give a result of
"You currently have 3 accounts."
Not without using the MessageFormat class, such as:
String pattern = bundle.getString("example.dynamicresource");
String message = MessageFormat.format(pattern, accountCount);
On their own, ResourceBundle does not support property placeholders. The usual idea is to take the String you get from the bundle, and stick it into a MessageFormat, and then use that to get your parameterized message.
If you're using JSP/JSTL, then you can combine <fmt:message> and <fmt:param> to do this, which uses ResourceBundle and MessageFormat under the covers.
If you happen to be using Spring, then it has the ResourceBundleMessageSource which does something similar, and can be used anywhere in your program. This MessageSource abstraction (combined with MessageSourceAccessor) is much nicer to use than ResourceBundle.
There are various ways, depending on the view technology you're using. If you're using "plain vanilla" Java (e.g. Swing), then use MessageFormat API as answered before. If you're using a webapplication framework (which is true, if I judge your question history here correctly), then the way depends on the view technology and/or MVC framework you're using. If it is for example "plain vanilla" JSP, then you can use JSTL fmt:message for this.
<fmt:message key="example.dynamicresource">
<fmt:param value="${bean.accountCount}">
</fmt:message>
If it is for example JSF, you can use h:outputFormat for this.
<h:outputFormat value="#{bundle['example.dynamicresource']}">
<f:param value="#{bean.accountCount}">
</h:outputFormat>
Best place is to just consult the documentation of the technology/framework you're using (or to tell it here so that we can give better suited and more detailed answers).
Struts have a nice util called MessageResources which does exactly what you ask for....
e.g.
MessageResources resources = getResources(request, "my_resource_bundle"); // Call your bundle exactly like ResourceBundle.getBundle() method
resources.getMessage("example.dynamicresource",accountCount,param2,...);
Limitation
It only allows maximum of 3 parameters (i.e. resource attribute, param1, ..., param3).
I suggest using MessageFormat (if you want to use more than 3 parameter values) as suggested by David Sykes.
PS the getResources method is available only in the Struts Action class.
I don't think you can make this work for Non-English properties file.
My message.properties file has the following line:
info.fomat.log.message.start=Starting to parse log message in {0} format.
And my message_fr_FR.properties file has the following line:
info.fomat.log.message.start=A partir d'analyser le message connecter {0} format.
This code works only for the English one
String.format((String) messages .getString(GlobalConstants.MESSAGE_FORMAT_START), GlobalConstants.STR_JSON));
It does NOT replace the placeholder with the value when my language / locale is French :-(
Even MessageFormat.fomat() is no good
I don't believe ResourceBundle can do that itself, but String can:
String.format(bundle.getString("example.dynamicresource"), accountCount);
Remember that when using MessageFormat.format() you need to use a double quote ('') in your resource bundle if you want to express single quote (').
MessageFormoat#format will work for the case like:
greetingTo=Have Param, saying hello {0}
You can declare two methods like this where RB is a instance of ResourceBundle:
/**This is a method that takes the param to substitute the placeholder**/
public String getString(String key, Object... params ) {
try {
return MessageFormat.format(this.RB.getString(key), params);
} catch (MissingResourceException e) {
return "[" + key + "]";
}
}
/**Without a param, this will derectly delegate to ResourceBundle#getString**/
public String getString(String key) {
try {
return this.RB.getString(key);
} catch (MissingResourceException e) {
return "[" + key + "]";
}
}

ResourceBundle from Java/Struts and replace expressions

If I have a Resource bundle property file:
A.properties:
thekey={0} This is a test
And then I have java code that loads the resource bundle:
ResourceBundle labels = ResourceBundle.getBundle("A", currentLocale);
labels.getString("thekey");
How can I replace the {0} text with some value
labels.getString("thekey", "Yes!!!");
Such that the output comes out as:
Yes!!! This is a test.
There are no methods that are part of Resource Bundle to do this. Also, I am in Struts, is there some way to use MessageProperties to do the replacement.
The class you're looking for is java.text.MessageFormat; specifically, calling
MessageFormat.format("{0} This {1} a test", new Object[] {"Yes!!!", "is"});
or
MessageFormat.format("{0} This {1} a test", "Yes!!!", "is");
will return
"Yes!!! This is a test"
[Unfortunately, I can't help with the Struts connection, although this looks relevant.]
There is the class org.apache.struts.util.MessageResources with various methods getMessage, some of them take arguments to insert to the actual message.
Eg.:
messageResources.getMessage("thekey", "Yes!!!");

Categories

Resources