A few different customers have raised questions over the last few months about how they might approach managing all of their translatable text from a single XML file, instead of as a number of component-specific Java message bundle files. I prepared a small example in GenMessageBundles.zip that you can download to check out one possible approach.
This approach is not to change the way that resources are handled at runtime, but instead to simply give you some ideas for how you might automate the generation of BC4J-component-specific message bundles for multiple languages based on storing all of the messages in a single XML file like the included AllMessages.xml file. In this case, I just invented a few XML elements like <Mod> for a module and <Ent> for an entity and <Att> for an attribute and <Msg> for a translatable message. If there is some industry standand XML format for translatable messages, you could adopt the example to use that format instead.
The GenMessageBundles.xsl file makes use of the multiple-output-file feature of XSLT which is something that most XSLT processors support but which unfortunately did not make it into the standard set of XSLT 1.0 features. In other words, each vendor whose XSLT engine supports it does it a slightly different way until XSLT 2.0 comes out. This XSLT stylesheet is written using the <ora:output> tag which the Oracle XSLT engine supports. Since the Oracle XSLT engine is a core part of the Oracle XML Developers kit which ships with every release of JDeveloper, you already have the "bits" you need to make this example work if you have JDeveloper 9.0.3.X.
Finally, the build.xml script is a simple Ant script that contains two build targets rebuild-default-messages and rebuild-italian-messages. To see the sample in action, you'll need to:
- Create a working directory and unzip the three files in the GenMessageBundles.zip into it
- Edit the build.xml file so that the value of the jdev_home variable points to the root directory of your JDeveloper 9.0.3 installation
- Change directory into this new directory, and do an Ant build.
If you are using a version of "ant" that is in your system path, then you can just type ant and it will build the default target. To build the italian language resource bundles, you would type "ant rebuild-italian-messages".
If you are using the ant that comes with JDeveloper, you can substitute "java -jar <jdevhome>/jdev/lib/ant.jar" where you see ant in the two commands above.
After running the build, you'll see that down in the appropriate ".common" subdirectory of the package directory for the two example entity objects whose messages appear in AllMessages.xml, you will find the appropriate generated *ImplMessageBundle.java and *ImplMessageBundle_it.java files.
The last piece of the puzzle is the reference that your BC4J components have to their default message bundle file. You'll see that each XML component definition that supports a related message bundle (entity objects and view objects principally) there will be an XML attribute named MsgBundleClass. The default value for this attribute will be the default BC4J message bundle class name oracle.jbo.common.JboResourceBundle. However, once the BC4J design time has stored as least one string in the custom component message bundle, then it will change the value of this attribute in the respective component's XML file to reflect the name of the default custom message bundle class like "com.company.app.model.common.YourEntityImplMsgBundle".