Using Eclipse externalized Strings - how to get a String in language XYZ? - java

In our Eclipse RCP application, all Strings are externalized and present in 2 languages, which works just fine.
E.g. I got a Messages.java like this:
public class Messages extends NLS
{
private static final String BUNDLE_NAME =
"abc.fixedcolumns.messages"; //$NON-NLS-1$
public static String additionalReq;
static
{
// initialize resource bundle
NLS.initializeMessages( BUNDLE_NAME, Messages.class );
}
private Messages()
{
super();
}
With the matching messages_de.properties and messages_en.properties.
It works fine, starting the application in english shows the english strings and in german shows the german ones.
Now I need to get some English strings in the german version.
How can this be accomplished?
(One attempt was to change the Locale of the JVM, get the string and change it back, but this would be a very bad solution)

You don't have to put all your messages in the language specific properties file. NLS will also look in a messages.properties file. You could put the English only messages there and not put anything in the language specific properties.
Other than that NLS does not support doing a lookup for anything other than the current locale. You could make your own version of the class to do what you want, NLS is not very big.
Eclipse e4 RCPs do support more flexible translation systems.

Related

Java resource bundle is loaded from another module

Currently my project contains 3 modules, 1 named generic (which is based for other 2) ,
first named Romania and second named Cyprus, inside of them i have a little code (which does not contain the logic of calling bundles). In the all 3 modules i have resources -> language and here i have first_en_US_CUSTOM (Cyprus module) , first_en_US_CUSTOM (generic module) and same in the Romania. The logic to load this is:
private String getTranslated(ResourceBundle resourceBundle) { // resource bundle comes with locale en_US
String result = null;
try {
String text = resourceBundle.getString(key);
result = text;
} catch (MissingResourceException var7) {
System.out.println("No resource found");
}
return result;
}
While calling this (it is called from a JAR file) , it returns the string from Cyprus module, however Romanian module is running (obv. it should take it from Romanian module). if i remove the first_en_US from Cyprus module then i get it in Romanian moudule and generic one, however -> it takes from generic module now. What is the problem here? Where should i search? I am debugging and can't find at all the problem or where it loads from.
First (if you should not know it already): since java 9 *.properties can be edited in UTF-8, without \uXXXX which for Greek is great. The problem here is class path/locale related.
The Locale adds a suffix to the file. It could also be a problem using the same path to the properties but different contents. A problem when falling back on the generic root locale. (Maybe java's module system might help.)
ResourceBundle resourceBundle = ResourceBundle.getBundle("foo.bar.Baz", locale);

Eclipse RCP: InternalPlatform.getDefault().getUserLocation() doesen't return C:\Users\username\AppData\Roaming

I am currently migrating an Eclipse 3.0 application to 4.4. The user data was and still should be stored in the folder C:\Users\username\AppData\Roaming\applicationname
The application is using following code to read the directory:
public static String getUserDirectory()
{
String directory = InternalPlatform.getDefault().getUserLocation().getFile();
return directory;
}
I know the code is deprecated, but following code returns the same:
public static String getUserDirectory()
{
String directory = Platform.getUserLocation().getURL().getFile();
return directory;
}
They both return C:\Users\username\user but as I said the user data should be stored at C:\Users\username\AppData\Roaming\applicationname. Did the behaviour of those methods change?
How can I realize that I store my user data under C:\Users\username\AppData\Roaming\applicationname and my application can still find the directory?
I know this has to do something with environment-variables which I don't fully understand.
I don't have a 3.x target platform at hand to compare but C:\Users\username\user looks plain wrong.
If you are interested in the details, the constructor of EquinoxLocations computes the userLocation and adds the literal 'user' the the user's home directory if no default is specified.
Hence, if you start your application with -user #user.home or -Dosgi.user.area=#user.home, the user location will be set to C:\Users\username\. Still not what you are looking for, but at least a sane value.
I think this is a bug in Equinox and recommend to file a bugzilla. If it turns out that there is a good reason for this appraoch the bug entry will still serve as documentation/reasoning.
In the meanwhile you could obtain the home directory on Windows through System.getenv( "APPDATA" ). According to this post it will return the roaming home directory.
I solved the problem by adding three properties in the Configuration tab of my config.ini.product-file:
osgi.configuration.area =
#user.home/AppData/Roaming/ApplicationName/...
osgi.user.area =
#user.home/AppData/Roaming/ApplicationName/...
osgi.instance.area =
#user.home/AppData/Roaming/ApplicationName
Now my method as stated in my question reads the paths that are configured by those properties and the config.ini file which is generated looks exactly like the one of the old build with Eclipse 3.0.

Java xml-parsing using Simple returns ??? instead of greek letters

I am trying to get the values of from the following xml, but the code i've written returns a bunch of question-marks instead of what it was supposed to return. I'm guessing it must be some encoding issue, but I haven't found anything about that yet on the web.
<channel>
<title>ΖΩΔΙΑ Προβλέψεις, 1 Σεπτεμβρίου 2012</title>
</channel>
zodiaClass.java
public class zodiaClass {
#Root(strict = false)
public static class Example {
#Path("channel")
#Element
private String title;
}
public static void main(String[] list) throws Exception {
Persister persister = new Persister();
File file = new File("example1/download.xml");
Example example = persister.read(Example.class, file);
System.out.println(example.title);
}
}
output:
????? ??????????, 1 ??????????? 2012
[As requested, this is a translation of the above comment thread into the form of an answer.]
I suspect that the issue is with the output, rather than with the input. Not all command-line environments support Greek. To test this, you can try System.out.println("\u03B1"); if your command-line supports Greek, it should show up as α (lowercase alpha).
In one of your comments, you mention that you're using Eclipse. If it does turn out that the problem is with the output, then a Google search for Eclipse console encoding suggests that there are a number of different approaches that people have tried successfully — everything from modifying the relevant Run Configuration within Eclipse to editing eclipse.ini and the system encoding.
Update: [not really an update, but I'm trying to maintain the illusion of a regular answer . . .] I see from your follow-up comment that you were able to change the console encoding by changing the encoding of the *.java file. Cool!

gettext-common example doesn't work

I need to translate my app, so i want to use gettext-common from http://code.google.com/p/gettext-commons
I checked out the svn and tried to compile the example:
javac -classpath ../java I18nExample.java
java -classpath ../../target/gettext-commons-0.9.6.jar:. I18nExample
The program does not give me the targeted output; I have absolutely no idea whats going on!
It seems that the de.properties is completly ignored. If I set the Properties file to "de" in the Factory's constructor, I get partly the output I want to see.
Is there anywhere in the internet a working example of gettext for java?
this is the output from the example script:
First run
This text is marked for translation and is translated
This text is marked for translation but not translated
This text is marked for translation but not translated
Four: 4
chat
chat
1 file is open
2 files are open
Second run
This text is marked for translation and is translated
This text is marked for translation but not translated
This text is marked for translation but not translated
Four: 4
chat
chat
1 file is open
2 files are open
There are a couple of issues, perhaps due to the build process.
First, for the message lookup to work, I needed to move the en and de resources into Messages_en.properties and Messages_de.properties in order to make a real resource bundle.
Second, the example code tries to use messages with no translations available, like the "file is open" stuff. Here's an updated version of what I tried; this all appears to work with the above modification:
public static void main(String[] args) {
I18n i18n = I18nFactory.getI18n(I18nExample.class, "Messages");
for (int i = 0; i < 2; i++) {
if (i == 0) {
print("First run");
} else {
print("Second run");
i18n.setLocale(Locale.GERMAN);
}
print("Current locale: " + i18n.getLocale());
print(i18n.tr("This text is marked for translation and is translated"));
String mark = i18n.marktr("This text is marked for translation but not translated");
print(mark);
print(i18n.tr(mark));
mark = i18n.tr("This is the {0}. text to be translated", "chat (noun)");
print(mark);
mark = i18n.tr("This is the {0}. text to be translated", "chat (verb)");
print(mark);
print(i18n.tr("chat (noun)"));
print(i18n.tr("chat (verb)"));
print("");
}
}
Note also that to insert translated words, you need something like this:
print(i18n.tr("This is the {0}. text to be translated", i18n.tr("chat (noun)")));
print(i18n.tr("This is the {0}. text to be translated", i18n.tr("chat (verb)")));
However, without un-banging (removing the ! and providing an English translation in Messages_en.properties, it shows up as chat (noun), which... strikes me as being almost useless.
The documentation is lacking on this aspect.

GWT I18N on the server side

What is the best way to implement GWT Server Side Internationalization?
Use native Java properties files (not sure how to read and how to locate the right language file) (unicode string need to be ASCII encoded)
Use GWTI18N.java - GWT module which gives you seamless use of GWT I18N on both the client and the server and uses "java.lang.reflect.Proxy method"
Use Kotori I18N - ...
Other ideas?
How can I find and pass localization from client to sever?
On the server side I have an Servlet which still doesn't use any GWT dependant source, is it better not to do so?
I found this solution and it looks very good
gwt-i18n-server - Provides a simple support of gwt i18n feature on the server side
The aim is to permit to the GWT developer to use their Constants and Messages interfaces on the server side (See internationzation). The implementation is based on java reflect api. It loads the properties files from the classpath (same folder than the interface). It supports Constants, ConstantsWithLookup, Messages (plural too). The licence is LGPL.
Client current locale can be found this way:
LocaleInfo.getCurrentLocale().getLocaleName()
Following other threads here in SO, I came up with this solution that also considers the encoding used for the properties files (which can be troublesome as ResourceBundle uses by default "ISO-8859-1"):
import java.io.UnsupportedEncodingException;
import java.util.Locale;
import java.util.ResourceBundle;
public class MyResourceBundle {
// feature variables
private ResourceBundle bundle;
private String fileEncoding;
public MyResourceBundle(Locale locale, String fileEncoding){
this.bundle = ResourceBundle.getBundle("com.app.Bundle", locale);
this.fileEncoding = fileEncoding;
}
public MyResourceBundle(Locale locale){
this(locale, "UTF-8");
}
public String getString(String key){
String value = bundle.getString(key);
try {
return new String(value.getBytes("ISO-8859-1"), fileEncoding);
} catch (UnsupportedEncodingException e) {
return value;
}
}
}
The way to use this would be very similar than the regular ResourceBundle usage:
private MyResourceBundle labels = new MyResourceBundle("es", "UTF-8");
String label = labels.getString(key)
Or you can use the alternate constructor which uses UTF-8 by default:
private MyResourceBundle labels = new MyResourceBundle("es");

Categories