|
NLS Translator Tool for Documentum
| November 2007 | |
| Contributed by - Mitch Bird |
Abstract
This program assists in the creation of localized NLS files not included in the Documentum Language Packs. In other words, NLS files for all of your custom applications and objects, so long as you used NLS files for their strings. The program also helps fix the Documentum Language Pack NLS files that have missing entries.
The Story
Recently, I was called on to implement a Spanish version of an installation of
Webtop. This was for a relatively mature installation that included several
types of custom applications and more than just a few actual modifications to
the standard Documentum classes; the custom folder contained more than twenty
folders most of which contained subfolders. Altogether they reflected the
structures found within the standard Documentum folders like 'webcomponent',
and 'wdk' with the addition of the custom application's folders.
The first step, of course, was to install the Spanish Language pack to the war
folder which, it turned out, was very easy to do. The Language Pack file is a
zip file. When it is unpacked it creates a folder structure that contains the
same folder structure as the actual war folder. It is then just a simple
matter to copy that expanded folder right on top of the war folder and the
files all end up where they should go.
Another was to make a couple language config changes to an app.xml file. The
language config settings are to be entered in VIRTUAL_ROOT/webtop/app.xml or
if modified VIRTUAL_ROOT/custom/app.xml Those changes were as follows: add the
reference to Spanish in the 'supported_locales' section and set the
'fallback_to_english_locale' flag to true. Your language section might look as
follows:
<!-- language section -->
<language>
<supported_locales>
<locale>en_US</locale>
<locale lang="Spanish" version="5.3.0.308">es_ES</locale>
</supported_locales>
<default_locale>en_US</default_locale>
<fallback_to_english_locale>True</fallback_to_english_locale>
</language>
|
There were still a couple of small hurdles to deal with before I could
start. The first was that several of our custom applications had not made full
use of the NLS properties files for the storing and retrieval of strings.
Fixing that was pretty straightforward.
The next was that several other of our applications were written in DocBasic
and so could not take advantage of NLS properties files. Those applications
were automation type apps without any real interface components. So be it, re-
writing those applications was way outside of scope.
Another was that the headers in 'objectlist-type' components were not
displaying the labels associated with custom fields but rather the field names
themselves. I found an article on the EDN and followed the instructions to a
T. While I was doing it I was thinking to myself ... that doesn't make a lot
of sense. The way it was written every record would be examined to determine
its custom field's params. Hmmm. The article wanted me to modify the
'custom_attribute_data_handlers' tag in app.xml, then create an implementation
class based on ICustomAttributeDataHandler when really all I had to do was
configure.
Some interesting information about how Documentum stores field information can be found by running the following DQL and then doing a dump on a couple of the object ids returned:
select * from dm_type where name = 'some_custom_object_type'
select * from dmi_type_info where r_type_name = 'some_custom_object_type'
select * from dm_aggr_domain where type_name = 'some_custom_object_type'
|
What really needs to be done is adding references to your custom fields in the following files. If your company uses the Streamline interface then I think you will also have to modify... a couple other components.
The XML sections go into
VIRTUAL_ROOT/webcomponent/config/navigation/homecabinet/homecabinet_list_component.xml
and
VIRTUAL_ROOT/webcomponent/config/navigation/doclist/doclist_component.xml
Here is a sample of how to edit those files. The first entry makes it so
'r_object_id' column headings say 'Object ID' the rest are for a custom
application.
<!-- start missing from Documentum implementation -->
<column>
<attribute>r_object_id</attribute>
<label><nlsid>MSG_DDOC_OBJECT_ID</nlsid></label>
<visible>false</visible>
</column>
<!-- end missing from Documentum implementation -->
<!-- start CustomApp attributes -->
<column>
<attribute>mb_customapp_number</attribute>
<label><nlsid>MSG_MBCA_NUMBER</nlsid></label>
<visible>false</visible>
</column>
<column>
<attribute>mb_customapp_fiscal_year</attribute>
<label><nlsid>MSG_MBCA_FISCAL_YEAR</nlsid></label>
<visible>false</visible>
</column>
<column>
<attribute>mb_customapp_responsible</attribute>
<label><nlsid>MSG_MBCA_RESPONSIBLE</nlsid></label>
<visible>false</visible>
</column>
<column>
<attribute>mb_customapp_routing_date</attribute>
<label><nlsid>MSG_MBCA_ROUTING_DATE</nlsid></label>
<visible>false</visible>
</column>
<column>
<attribute>mb_customapp_routing_node</attribute>
<label><nlsid>MSG_MBCA_ROUTING_NODE</nlsid></label>
<visible>false</visible>
</column>
<column>
<attribute>mb_customapp_routing_note</attribute>
<label><nlsid>MSG_MBCA_ROUTING_NOTE</nlsid></label>
<visible>false</visible>
</column>
<column>
<attribute>mb_customapp_status</attribute>
<label><nlsid>MSG_MBCA_STATUS</nlsid></label>
<visible>false</visible>
</column>
<column>
<attribute>mb_customapp_type</attribute>
<label><nlsid>MSG_MBCA_TYPE</nlsid></label>
<visible>false</visible>
</column>
<column>
<attribute>mb_customapp_completion_date</attribute>
<label><nlsid>MSG_MBCA_COMPLETION_DATE</nlsid></label>
<visible>false</visible>
</column>
<column>
<attribute>mb_customapp_workflow_id</attribute>
<label><nlsid>MSG_MBCA_WORKFLOW_ID</nlsid></label>
<visible>false</visible>
</column>
<!-- end CustomApp attributes -->
|
Then, of course, the NLS'd key/value pairs go into the following files:
VIRTUAL_ROOT\custom\strings\com\documentum\custom\navigation\homecabinet\HomeCabinetListNlsProp.properties
and
VIRTUAL_ROOT\custom\strings\com\documentum\custom\navigation\doclist\DocListNlsProp.properties
A sample from those files follows:
#dm_document
MSG_DDOC_OBJECT_ID=Object ID
#CustomApp
MSG_MBCA_FISCAL_YEAR=Fiscal Year
MSG_MBCA_NUMBER=ID Number
MSG_MBCA_RESPONSIBLE=Responsible
MSG_MBCA_ROUTING_DATE=Routing Date
MSG_MBCA_ROUTING_NODE=Routing Node
MSG_MBCA_ROUTING_NOTE=Routing Note
MSG_MBCA_STATUS=Status
MSG_MBCA_TYPE=Type
MSG_MBCA_COMPLETION_DATE=Completion Date
MSG_MBCA_WORKFLOW_ID=Workflow ID
|
So with those things fixed I only had to create my NLS properties files for my
custom classes ... or so I thought. I did some preliminary checking into how
well the Language Pack had worked and found out there were quite a few
translations missing. Basically, the Language Pack files hadn't been updated
for about two years, and so, many new keys had never been translated. As I
started looking for the missing references, I began to realize why those keys
were missing.
Creating and tracking all of the key/value pairs and then verifying that each
one had a matching foreign translation was going to be nothing less than a
clerical nightmare.
The Need for a Tool
What I needed was a tool with a simple interface where all of the translations could be entered quickly and
conveniently. It would automatically replicate values whose keys are actually aliases for the same string so, for example, one would only have to translate the word 'Cancel' once.
It would need a special way to handle the 'NLS_INCLUDES=' keys, which can have
multiple comma separated references to other NLS files. Those values need to
be automatically changed to reference the foreign language versions.
Because I don't actually speak Spanish and wouldn't be sitting there with the
person doing the actual translating, the interface had to be easy to use and
understand, and include the ability for the translator to flag any key/value
pairs that he might have a question about. It should also automatically flag
any values containing arguments, like {0}, {1} so that I (or some other
programmer) could verify they are still syntactically correct before generating
the new NLS files. Also, anomalies like empty values in the English properties
files should be flagged.
I thought about creating a 'commented line' tracker to regenerate included
comments but never got around to it. A nice report should be generated, too.
Another thing that my translator might thank me for would be a button that
simply enters the English string into the translation for 'internationalized'
English values like 'Microsoft Word'.
A way to verify the completeness of the NLS files that came in the Language
Pack, is critical. The tool should make the incremental updating of sets of
NLS files quick and painless so the form should be able to filter up only the
untranslated key/value pairs at any time while the translator is entering
data. In other words, when they get back from lunch and still have 250 k/v
pairs left to translate. The tool should be able to quickly add the missing
key/value pairs and re-generate the updated files. Those files should be
created into a pseudo copy of the folder structure; just like the Language
Packs themselves, in order to make installing them just as simple.
At the same time, the tool should quickly create all of the NLS files for my
custom applications which should also follow the same folder structure rules
as the standard files so that the final installation is one simple copy and
paste ... piece of cake.
Lastly, it would be nice if the program could start from any folder so that
only the custom apps might be worked or even an entire Documentum install
including all of the applications and not just Webtop.
The Plan
I thought a simple VB/ADO application with a Microsoft Access database as the back end
would do the trick nicely. I am an old hand at that but in VB6 using classic ADO. I thought this would be an excellent opportunity to expand my horizons by doing it in .NET and with a few of those new fangled ADO data adapter thingies. The Access database would have a data entry form built right in. For the translator's convenience I would use the old 'autoexec' trick to make the form open by default and to hide my actual tables. The front end (the VB.NET part) would have a config screen for setting up the flowerbox contents, for locating the folder from which to get the data, and lastly, for creating and monitoring the creation of the new NLS properties files/folders.
The Answer
Download the install file and unzip it to your desktop. Inside the folder that will be created are both the install files and the Access file that
will hold the data. Make a copy of the Access file somewhere and keep the it as your template. Run setup.exe and try it out.
If you are not actually doing a localization project right now but would
like to try out the program anyway, you can easily do that by just creating
a small folder heirarchy and copying some of your 'properties' files into
the folders. In that way you can quickly walk through the whole process
with a minimum of data entry.
During initial setup of a translation, the user enters information which will become
the flowerbox - header section - of the generated NLS files.
Data entry is done in a streamlined interface that handles redundant values by requiring
only a single entry. So, for example, if you have 50 Keys which are all aliases for
the word 'false', your translator will only have to enter a translation for one them
and all of the rest will be filled in automatically. There is also a checkbox which the
translator can use to mark entries that he feels need clarification or special attention.
The program works for any of the single byte languages and may work for double byte
languages, but in all honesty, it was just too much trouble to set up the testing.
How Does It Work?
It is recommended that the program be run against a copy of the actual war folder, just to
be safe. Not that anything would go wrong, but it is a best practice to keep your original files
secure.
The program recursively goes through a copy of an application's war folder, for
example 'webtop.war', and finds all files that end in '.properties'. Files under the 'custom'
folder are automatically processed and files under the other folders are checked for
completeness/existence against the assumed localized version.
In other words, when the progarm gets to the ...
'webtop.war\webcomponent\strings\com\documentum\webcomponent\navigation\doclist'
folder, if the program is working on a spanish translation i.e., _es_ES, then the program
will be looking for a file called 'DocListNlsProp_es_ES.properties' that goes along with the
'DocListNlsProp.properties' file. If it finds the file it will compare the two and verify
that there exists a matching entry for each of the entries in the original file.
If it doesn't find the file it will treat the matter just like a 'custom' NLS file and
process the data into the database for creation of a localized version.
I found that many of the Documentum provided Language Pack NLS files were missing entries
and also that quite a few of the standard OOTB NLS files did not have localized versions
included in the Language Pack.
The program gathers all of the key/value pairs from the NLS files identified as to be included
into an Access database along with their paths and file names. The program then identifies values
that may need special treatment - containing arguments like {0}, {1} - and flags them
for final review. It then marks duplicate values, so the translator only has to translate each
unique value once. Finally, it applies special treatment to 'NLS_INCLUDES' tags.
At this point, the Access database is ready to hand off to the translator.
When the translator opens the database, a form appears where she can enter the translations.
This form automatically opens when the file is opened.
In order to open a standard view of the database, the user must hold down the shift
key from before double clicking the file icon until the file is completely open.
This makes it so the average user will only see the 'Enter Translations' form.
Once all the translations have been entered, open the Access file with this program again
and once opened, click the 'Create New Locale Files' button.
A dialog appears asking where the program should create the files.
The program creates a folder structure which mirrors the original war folder's structure.
The original war folder should not be used for this because the translation folders
will be created in a root folder called 'NLSTranslations' and would therefore not end up
in the original folders.
Once finished a report will also be in the root of that folder, identifying various entries
that may require special attention. Review that report before moving the files into the war folder.
That's it. Instant - or at least relatively so - localization of your Documentum applications.
Note: If you are processing a very large extraction, the program may appear to lock up for a moment (but never really does), owing to the extraction process being a linear and processor intensive algorithm, but it will finish in a moment or two.
Screen Shots
Click on photos for larger images
Main screen
Configuration screen
Main screen after processing
Data entry screen
About the Author
Mitch Bird has over 10 years experience programming; with professional projects written in .Net, Java, PHP, COBOL, and several other languages. He wrote the MrDistrict CRM program (www.mrdistrict.com) used by many State and Local politicians. He is somewhat new to Documentum, though, and has been programming with DFC/WDK about a year. Mitch has written several Enterprise DocApps and created about a dozen utilities for such things as DocApp Creation automation, Index Agent Maintenance and Monitoring, InputAccel and Method server monitors, file migration tools and others. He can be reached at mitchbird@birdco.net. Mitch is willing to send the source code for this project to those who request it via email.
Discuss
Click here to discuss this article
|