Keeping i18n resources synced - java

I am looking for an editor/comparator for i18n property files that would help me keep different language files in sync.
Basically, something that would compare a bunch a of property files and show which keys are not present in a particular language.
a property would look something like
component.titlepage.title = hello world
A simple diff is not possible since the right-hand-side will be different from a language to another.
Our current infrastructure:
Java application
Built using maven2
Different i18n property files for different components of the system. (1 property file per language per component)

The Checkstyle tool, which I typically run as part of every continuous integration build which is done after every check-in to the main branch, will tell you if any given set of properties files has an inconsistent set of properties. When I first started using Checkstyle, I indeed found that a few of my properties files were missing a small number of properties.
This won't help on the editor end, but it will help you efficiently identify any gaps.

If you are using Eclipse, I find the ResourceBundle Editor plugin very handy. You can edit several properties files at the same time and you have warnings when a key is missing in one of the files.

There are also a number of web applications that allow you to do that (along with many other activities). To name a few:
Amanuens (disclaimer: my company builds this product)
Transifex
Get Localization

Related

Is there any way to reorder projects in the package/project explorer in Eclipse?

I'm working on source code that is split across several projects with a specifically defined build order. I want to see the projects sorted by the build order so I can always tell which classes can be used in which projects. Does anyone know how to do this in Eclipse Kepler?
If you are not already using working sets in Eclipse, they provide a good way to organize your projects. The organization is single-level, rather than hierarchical, but you can group projects and then quicly select in the project explorer view settings whether you want the working sets to be shown or not. A potentially useful detail is that a project may be contained in multiple working sets, so that you can have multiple grouping criteria at the same time.
In your case, you could define a working set for each phase of your build, prefixing its name with a letter or number that would ensure its presentation in a specific order. Or you could define a working set for each set of projects with the same dependencies.
Alternatively, you might be able to just rename your projects appropriately. In many cases the project name itself is mostly cosmetic, although it is often used as a default in generated files.
In my opinion, however, the easiest way to "tell which classes can be used" is to just configure your project build paths correctly and let the editor do the rest. For me it is more natural not to use a class because it is not proposed for auto-completion or because any such use results in a compiler error, rather than explicitly checking the dependencies each and every time...
IMHO there is no such feature in eclipse. But you can use Resource Tagger plugin or Resource decorator plugin and filter the resources based on different conditions.

Is there a way to load multiple application properties files in Apache Wicket?

My WicketApplication.properties file has grown very large, and now to keep it more readable I want to categorize properties in different files. Is there a way to accomplish that and still access the properties like if they were all in the WicketApplication.properties?
See org.apache.wicket.settings.IResourceSettings.addStringResourceLoader(IStringResourceLoader).
You can implement your own IStringResourceLoader which may load from wherever your want.
You can use property files dedicated per page or even component:
AddressPicker.properties - properties specific to an AddressPicker.java componen
ProfilePage.properties - properties used only on a given page (ProfilePage.java)
WicketApplication.properties - for aplication-wide properties (WicketApplication.java)
Wicket, when looking for properties for a given component, will look for the property files in the same order as above. AFAIR Struts2 uses exactly the same technic.
Please look at Wicket documentation: https://cwiki.apache.org/WICKET/i18n-and-resource-bundles.html.
As a last resort, you could write multiple files, but merge them into a single WicketApplication.properties as part of your build process. Unix has a tool precisely for doing this.

Java preprocess phase

I'm writing a Java application that needs a lot of static data that is stored in many enum types. Since I would like an user-friendly way to customize this data using for example xml or json files but I'm not allowed to do it directly with enums I was looking for a way to elegantly do it.
Maybe a good solution would be to have a separate java program that reads the xml files and produces the java sources that are then compiled with the remaining part of the sources. My doubs is how to automatize this process in a stand alone way (eg ant?) and how to integrate it seamlessly with eclipse so that it is autOmatically done when I'm working with the project.. Does anything similar to what I'm looking already exists? Any suggestion to solve my problem?
Thanks!
If the items and the overall structure are somehow fixed (and what varies most is the values of the attributes), you could consider defining the enum with one entry for each of your items and let the enum populate its own constants with data read from an external source (XML / JSON) -- at load time or on demand.
Create a project whose sole job is to generate java from your sources.
Make sure that the generation phase is done by Ant.
Now, wrap this project into eclipse and use a custom ant builder, that calls the target in your already existing build.xml.
This is a standard part of our dev infrastructure, so this definitely works.
You can write a maven plugin that generates the code. There are some plugins that do that. It won't work automatically, but you can connect it to the standard maven lifecycle so it gets executed just before compile.
I just did something like that recently.
You can have ant seamlessly integrate with eclipse to achive that:
In Eclipse open project properties, go to "Builders", click "New...", select "Ant Builder", select a build file, go to "Targets" tab and click "Set Targets..." for "Auto Build". Select the desired target and you are done. The target will run every time you save a source file (if "Build Automatically" is selected).
Have you considered including the XML files in your jar, and loading them on startup into maps that use the enum as a key?

Java tip for plugin-like architecture

My application will output a graph, for which the layout is to be defined by the user. The custom layout class should implement an interface defined by me.
How should I do this? Have a special folder where I look for layout classes? Have the user pass the class name as argument to the app?
Any help would be greatly appreciated.
Multiple approaches used at the same time usually give the best results here. Different users may choose different ways to configure your application. For example:
A default directory where users can put plugins. Or even a list of directories, which could include some subdirectory of the application folder, some system-wide directory in the platform-dependent "application data" place, some user-local directory.
A config file with some options to control plugins search and selection.
A Java system property which specifies a list of directories to search for plugins, like java -Dorg.something.appname.plugindirs=plugindir1;plugindir2.
A special command-line option or Java system property to select a particular plugin, possibly providing an absolute path or just a name to look up in the directories specified by the methods above.
I think that the more ways your application provide, the better. Of course, it should have some sort of default setup so users won't have to bother with all that stuff if they don't want to. Also, the order of using those options should be sensible: for example, it makes perfect sense for the user plugins to override the system ones, not the other way around.
The model chosen by toolkits years over, AWT, Swing, etc. is to be passed the layout as an argument to your API. Assuming you're being invoked from the commandline:
java -jar yourapp.jar;theirintf.jar yourapp org.example.theirintf
Don't try and be overly magical with special folders and conventions. Just take it as an argument. Please have a default value if the user choose not to create one of their own - your app should be usable on it's own.

What is the proper way to store app's conf data in Java?

Where do you store user-specific and machine-specific runtime configuration data for J2SE application?
(For example, C:\Users\USERNAME\AppData\Roaming</em> on Windows and /home/username on Unix)
How do you get these locations in the filesystem in platform-independent way?
First on the format:
Java property files are good for key/value pairs (also automatically handle the newline chars). A degree of structure is possible by using 'dot notation'. Drawback is that the structure does not allow you to easily enumerate top-level configuration entities and work in drill-down manner. Best used for a small set of often tweakable environment-specific settings
XML files - quite often used for more complex configuration of various Java frameworks (notably J2EE and Spring). I would advice that you at least learn about Spring - it contains many ideas worth knowing even if you decide not to use it. If you decide to roll your own XML configuration, I'd recommend using XStream with customized serialization options or if you just need to parse some XML, take a look at XOM. BTW Spring also allows you to plug your custom XML configuration language, but it's a relatively complex task. XML configuration is best used for more complex 'internal' configuration that is not seen or tweaked by the end user.
Serialized Java objects - a quick and easy way to persist the state of an object and restore it later. Useful if you write a configuration GUI and you don't care if the configuration is human readable. Beware of compatibility issues when you evolve classes.
Preferences - introduced in Java 1.4, allow you to store typed text, numbers, byte arrays and other primitives in platform-specific storage. On Windows, that is the registry (you can choose between /Software/JavaSoft/Prefs under HKLM or HKCU). Under Unix the same API creates files under the user home or /etc. Each prefs hive can be exported and imported as XML file. You can specify custom implementation of the PreferencesFactory interface by setting the "java.util.prefs.PreferencesFactory" JVM property to your implementation class name.
In general using the prefs API can be a good or a bad thing based on your app scenario.
If you plan to have multiple versions of the same code running on the same machine with different configuration, then using the Preferences API is a bad idea.
If you plan using the application in a restricted environment (Windows domain or tightly managed Unix box) you need to make sure that you have proper access to the necessary registry keys/directories. This has caught me by surprise more than once.
Beware from roaming profiles (replicated home dirs) they make up for some funny scenarios when more than one active machines are involved.
Preferences are not as obvious as a configuration file under the application's directory. most of the desktop support staff doesn't expect and doesn't like them.
Regarding the file layout of the prefs it again depends on your application. A generic suggestion is:
Package most of your XML files inside application's JAR either in the root or under /META-INF directory. These files will be read-only and are considered private for the application.
Put the user modifiable configuration under $APP_HOME/conf . It should consist mainly of properties files and occasionally a simple XML file (XStream serialization). These files are tweaked as part of the installation process and are usually not user serviceable.
Under the user-home, in a dot-directory (i.e. '~/.myapplication') store any user configuration. The user configuration may override the one in the application conf directory. Any changes made from within the application go here (see also next point).
You can also use an $APP_HOME/var directory to store any other mutable data which is specific to this application instance (as opposed to the user). Another advantage of this approach is that you can move and backup the whole application and it's configuration by simple copy of one directory.
This illustrates some standard techniques for managing configuration. You can implement them using different libraries and tools, starting from raw JRE, adding Spring/Guice or going for a full J2EE container (possibly with embedded Spring)
Other approaches for managing configuration are:
Using multiple base directories for running multiple instances of the application using different configurations.
Using lightweight registries for centralized configuration management
A centrally managed Configuration Management Database (CMDB) file, containing the host-specific values for each machine is rsync-ed every night to all production hosts. The application uses a templated configuration and selects from the CMDB during runtime based on the current hostname.
That depends on your kind of J2SE Application:
J2SE executable JAR file (very simple): use user.home System property to find home-dir. Then make a subdir accordingly (like e.g. PGP, SVN, ... do)
Java Web Start provides very nice included methods to safe properties. Always user-specific
Finally Eclipse RCP: There you have the notion of the workspace (also derived from user.home) for users and configuration (not totally sure how to access that tricky in Vista) for computer wide usage
All these approaches are, when used with care -- use correct separatorChar -- OS neutral.
Java has a library specifically for doing this in java.util.prefs.Preferences.
Preferences userPrefs = Preferences.getUserNodeForPackage(MyClass.class); // Gets user preferences node for MyClass
Preferences systemPrefs = Preferences.getSysteNodeForPackage(MyClass.class); // Gets system preferences node for MyClass
Preferences userPrefsRoot = Preferences.getUserRoot(); // Gets user preferences root node
Preferences systemPrefsRoot = Preferences.getSystemRoot(); // Gets system preferences root node
I use this
String pathFile = null;
if(OS.contains("win")){
pathFile = System.getenv("AppData");
}else{
pathFile = System.getProperty("user.home");
}
I save the settings of my application here
C:\Users\USERNAME\AppData\ on windows
user.home (/home/USERNAME) on other platfroms
For user specific config, you could write a config file to the folder pointed to by the "user.home" system property. Would only work on that machine of course.
You might want to look at Resource Bundles.

Categories

Resources