rsitze 2002/09/28 19:48:16 Modified: java/docs developers-guide.html integration-guide.html Log: Updated internationalization: Moved developer info from integration guide to developers guide. Described how to use the message file extension mechanism, and how it works. Revision Changes Path 1.29 +115 -19 xml-axis/java/docs/developers-guide.html Index: developers-guide.html =================================================================== RCS file: /home/cvs/xml-axis/java/docs/developers-guide.html,v retrieving revision 1.28 retrieving revision 1.29 diff -u -r1.28 -r1.29 --- developers-guide.html 10 Sep 2002 21:02:14 -0000 1.28 +++ developers-guide.html 29 Sep 2002 02:48:16 -0000 1.29 @@ -37,6 +37,7 @@ <br><a href="#Exception Handling">Exception Handling</a> <br><a href="#Compile And Run">Compile and Run</a> <br><a href="#Internationalization">Internationalization</a> +<br> <a href="#Extending Message Files">Extending Message Files</a> <br><a href="#Adding Testcases">Adding Testcases</a> <br><a href="#TestStructure">Test and Samples Structure</a> <br><a href="#CodeChecks">Adding Source Code Checks</a> @@ -132,14 +133,14 @@ For example, <code>org.apache.axis.components.logger.LogFactory</code> is the factory, or discovery mechanism, for the logger component/service. <p> -The <code>org.apache.axis.components.bytecode</code> package demonstrates -both a factory, and supporting classes for different bytecode tools used -by axis. This is representative of a pluggable component that uses -external tooling, but isolates them behind a 'thin' wrapper to AXIS, -providing only the limited interface required by AXIS. +The <code>org.apache.axis.components.image</code> package demonstrates +both a factory, and supporting classes for different image tools used +by AXIS. This is representative of a pluggable component that uses +external tooling, isolating it behind a 'thin' wrapper to AXIS that +provides only a limited interface to meet AXIS minimal requirements. This allows future designers and implementors to gain an explicit understanding of the AXIS's -requirements on these tools. +specific requirements on these tools. <h3> <a NAME="Logging/Tracing"></a>Logging/Tracing</h3> AXIS logging and tracing is based on the Logging component of the @@ -358,8 +359,8 @@ AXIS is in the process of moving away from using system properties as the primary point of internal configuration. Avoid calling <code>System.getProperty()</code>, -and instead call <code>AxisEngine.getGlobalProperty</code>. -<code>AxisEngine.getGlobalProperty</code> will +and instead call <code>AxisProperties.getProperty</code>. +<code>AxisProperties.getProperty</code> will call <code>System.getProperty</code>, and will (eventually) query other sources of configuration information. <p> @@ -367,11 +368,6 @@ global configuration system to be redesigned to better support multiple AXIS engines in a single JVM. -<p> -A <code>getGlobalProperty()</code> method has also been added -to <code>BasicHandler</code>. -Handlers (ancestors of <code>BasicHandler</code>) should use this local method -rather than accessing <code>AxisEngine.getGlobalProperty</code>. <h2> <a NAME="Exception Handling"></a>Exception Handling</h2> @@ -574,17 +570,20 @@ If you make changes to the source code that results in the generation of text (error messages or debug information), you must follow the following guidelines to ensure that your text is properly translated. -<br> +<h3> +<a NAME="Developer Guidelines"></a>Developer Guidelines</h3> <ol> <li> Your text string should be added as a property to the resource.properties -file (xml-axis/java/src/org/apache/axis/utils/resource.properties). +file (xml-axis/java/src/org/apache/axis/i18n/resource.properties). Note that some of the utility applications (i.e. tcpmon) have their own -resource property files (tcpmon.properties).</li> - +resource property files (tcpmon.properties). +</li> <br> <li> The resource.properties file contains translation and usage instructions. +Entries in a message resource file are of the form +<font color="#009900"><key>=<message></font>. Here is an example message:</li> <p> <p><font color="#009900">sample00=My name is {0}, and my title is {1}.</font> @@ -601,11 +600,12 @@ </ol> <li> The code should use the -static method org.apache.axis.utils.JavaUtils.getMessage +static method org.apache.axis.i18n.Messages.getMessage to obtain the text and add inserts. Here is an example usage:</li> <p> -<p><font color="#009900">JavaUtils.getMessage("sample00", "Rich Scheuerle", +<p><font color="#009900">Messages.getMessage("sample00", "Rich Scheuerle", "Software Developer");</font> + <br> <li> <font color="#000000">All keys in the properties file should use the syntax @@ -627,8 +627,104 @@ <li> <font color="#000000">All new entries should be placed at the bottom of the file to ease translation.</font></li> + +<br> +<li> +<font color="#000000">We may occasionally want to trim the properties file of old data, but this should only be done on major releases. </font></li> </ol> </ol> + +<h4> +<a NAME="Example"></a>Example</h4> + +Consider the following statement: +<p><code> +if ( operationName == null )</code> +<br><code> +throw new AxisFault( "No operation name specified" );</code> +<p> +We will add an entry into +org/apache/axis/i18n/resource.properties: +<p><code> noOperation=No operation name specified.</code> +<p>And change the code to read: +<p><code> +if ( operationName == null )</code> +<br><code> +throw new AxisFault(Messages.getMessage("noOperation"));</code> + +<h3> +<a NAME="Interface"></a>Interface</h3> + +AXIS uses the standard Java internationalization class +<code>java.util.ResourceBundle</code> +to access property files and message strings, +and uses <code>java.text.MessageFormat</code> +to format the strings using variables. +AXIS provides a single class <code>org.apache.axis.i18n.Messages</code> +that manages both ResourceBundle and MessageFormat classes. +Messages methods are: + +<p><code>public static java.util.ResourceBundle getResourceBundle();</code> +<p><code>public static String getMessage(String key) throws java.util.MissingResourceException;</code> +<p><code>public static String getMessage(String key, String var) throws java.util.MissingResourceException;</code> +<p><code>public static String getMessage(String key, String var1, String var2) throws java.util.MissingResourceException;</code> +<p><code>public static String getMessage(String key, String[] vars) throws java.util.MissingResourceException;</code> + +<p>AXIS programmers can work with the resource bundle directly via a call +to <code>Messages.getResourceBundle()</code>, +but the <code>getMessage()</code> +methods should be used instead for two reasons: +<ol> +<li> +It's a shortcut. It is cleaner to call</li> + +<ol><code>Messages.getMessage("myMsg00");</code></ol> +than +<ol><code>Messages.getResourceBundle().getString("myMsg00");</code></ol> + +<br> +<li> +The <code>getMessage</code> methods enable messages with variables.</li> +</ol> + +<h4> +The getMessage methods</h4> +If you have a message with no variables +<ol><code>myMsg00=This is a string.</code></ol> +then simply call +<ol><code>Messages.getMessage("myMsg00");</code></ol> + +<p><br>If you have a message with variables, use the syntax +<font face="Courier New,Courier">"{X}"</font> +where <code>X</code> is +the number of the variable, starting at 0. For example: +<ol><code>myMsg00=My {0} is {1}.</code></ol> +then call: +<ol><code>Messages.getMessage("myMsg00","name", "Russell");</code></ol> +and the resulting string will be: "My name is Russell." +<p>You could also call the String array version of <font face="Courier New,Courier"><font size=-1>getMessage</font></font>: +<ol><code>Messages.getMessage("myMsg00", new String[] {"name", "Russell"});</code></ol> + +<p><br>The String array version of <font face="Courier New,Courier"><font size=-1>getMessage</font></font> +is all that is necessary, but the vast majority of messages will have 0, +1 or 2 variables, so the other <font face="Courier New,Courier"><font size=-1>getMessage</font></font> +methods are provided as a convenience to avoid the complexity of the String +array version. +<p>Note that the <font face="Courier New,Courier"><font size=-1>getMessage</font></font> +methods throw <font face="Courier New,Courier"><font size=-1>MissingResourceException</font></font> +if the resource cannot be found. And ParseException if there are +more {X} entries than arguments. These exceptions are <font face="Courier New,Courier"><font size=-1>RuntimeException'</font></font>s, +so the caller doesn't have to explicitly catch them. +<p>The resource bundle properties file is org/apache/axis/i18n/resource.properties. + +<h3> +<a NAME="Extending Message Files"></a>Extending Message Files</h3> +Generally, +within AXIS all messages are placed in +org.apache.axis.i18n.resource.properties. +There are facilities for extending the messages without +modifying this file for integration or 3rd party extensions to AXIS. +See the <a href="integration-guide.html#Extending Message Files"/>Integration Guide</a> for details. <h2> <a NAME="Adding Testcases"></a><font color="#000000">Adding Testcases</font></h2> 1.11 +155 -107 xml-axis/java/docs/integration-guide.html Index: integration-guide.html =================================================================== RCS file: /home/cvs/xml-axis/java/docs/integration-guide.html,v retrieving revision 1.10 retrieving revision 1.11 diff -u -r1.10 -r1.11 --- integration-guide.html 20 Sep 2002 20:55:02 -0000 1.10 +++ integration-guide.html 29 Sep 2002 02:48:16 -0000 1.11 @@ -285,104 +285,74 @@ <h3> <a NAME="Internationalization Plug"></a>Internationalization</h3> -The plug point for internationalization isn't a framework, but simply a -property file of the strings used in AXIS. -<br> +AXIS supports internationalization by providing +both a property file of the strings used in AXIS, +and an extension mechanism that facilitates +accessing internal AXIS messages and extending the messages +available to integration code based on existing AXIS code. + +<h4> +<a NAME="Translation"></a>Translation</h4> + <ul> <li> Justification/Rationale</li> -<br>In order for readers of languages other than English to be comfortable -with AXIS, we provide a mechanism for the strings used in AXIS to be translated. -We do not provide any translations in AXIS; we merely provide a means by -which translators can easily plug in their translations. -<br> -<li> -Interfaces</li> - -<br>AXIS uses the standard Java internationalization class: <font face="Courier New,Courier"><font size=-1>PropertyResourceBundle</font></font>. -To make this class easy to use, there are a number of methods on JavaUtils -that are used to get the messages within the resource bundle. -<p><font face="Courier New,Courier"><font size=-1>public static java.util.ResourceBundle -getMessageResourceBundle();</font></font> -<p><font face="Courier New,Courier"><font size=-1>public static String -getMessage(String key) throws java.util.MissingResourceException;</font></font> -<p><font face="Courier New,Courier"><font size=-1>public static String -getMessage(String key, String var) throws java.util.MissingResourceException;</font></font> -<p><font face="Courier New,Courier"><font size=-1>public static String -getMessage(String key, String var1, String var2) throws java.util.MissingResourceException;</font></font> -<p><font face="Courier New,Courier"><font size=-1>public static String -getMessage(String key, String[] vars) throws java.util.MissingResourceException;</font></font> -<p>AXIS programmers can work with the resource bundle directly via a call -to <font face="Courier New,Courier"><font size=-1>JavaUtils.getMessageResourceBundle</font></font>, -but the <font face="Courier New,Courier"><font size=-1>getMessage</font></font> -methods should be used instead for two reasons: -<br> -<ol> -<li> -It's a shortcut. It is cleaner to call</li> - -<ol><font face="Courier New,Courier"><font size=-1>JavaUtils.getMessage("myMsg00");</font></font></ol> -than -<ol><font face="Courier New,Courier"><font size=-1>JavaUtils.getMessageResourceBundle().getString("myMsg00");</font></font></ol> - -<li> -The <font face="Courier New,Courier"><font size=-1>getMessage</font></font> -methods enable messages with variables.</li> -</ol> - -<h4> -The getMessage methods</h4> -If you have a message with no variables -<ol><font face="Courier New,Courier"><font size=-1>myMsg00=This is a string.</font></font></ol> -then simply call -<ol><font face="Courier New,Courier"><font size=-1>JavaUtils.getMessage("myMsg00");</font></font></ol> - -<p><br>If you have a message with variables, use the syntax <font face="Courier New,Courier">"{X}"</font> -where <font face="Courier New,Courier"><font size=-1>X</font></font> is -the number of the variable, starting at 0. For example: -<ol><font face="Courier New,Courier"><font size=-1>myMsg00=My {0} is {1}.</font></font></ol> -then call: -<ol><font face="Courier New,Courier"><font size=-1>JavaUtils.getMessage("myMsg00", -"name", "Russell");</font></font></ol> -and the resulting string will be: "My name is Russell." -<p>You could also call the String array version of <font face="Courier New,Courier"><font size=-1>getMessage</font></font>: -<ol><font face="Courier New,Courier"><font size=-1>JavaUtils.getMessage("myMsg00", -new String[] {"name", "Russell"});</font></font></ol> - -<p><br>The String array version of <font face="Courier New,Courier"><font size=-1>getMessage</font></font> -is all that is necessary, but the vast majority of messages will have 0, -1 or 2 variables, so the other <font face="Courier New,Courier"><font size=-1>getMessage</font></font> -methods are provided as a convenience to avoid the complexity of the String -array version. -<p>Note that the <font face="Courier New,Courier"><font size=-1>getMessage</font></font> -methods throw <font face="Courier New,Courier"><font size=-1>MissingResourceException</font></font> -if the resource cannot be found. And ParseException if there are -more {X} entries than arguments. These exceptions are <font face="Courier New,Courier"><font size=-1>RuntimeException'</font></font>s, -so the caller doesn't have to explicitly catch them. -<p>The resource bundle properties file is org/apache/axis/i18n/resource.properties. +<br> +In order for readers of languages other than English +to be comfortable with AXIS, +we provide a mechanism for the strings used in AXIS to be translated. +We do not provide any translations in AXIS; +we merely provide a means by which translators +can easily plug in their translations. <br> + <li> Mechanism</li> +<br> +AXIS provides english messages in the +Java resource named +org.apache.axis.i18n.resource.properties +(in the source tree, the file is named +xml-axis/java/src/org/apache/axis/i18n/resource.properties). + +<p>AXIS makes use of the Java internationalization mechanism - +i.e., a java.util.ResourceBundle backed by a properties file - +and the java.text.MessageFormat class to substitute +parameters into the message text. + +<ul> +<br> +<li> +java.util.ResourceBundle retrieves message text +from a property file using a key provided by the program. +Entries in a message resource file are of the form +<key>=<message>. +</li> -<br>The Java internationalization mechanism - i.e., a ResourceBundle backed -by a properties file - and the java.text.MessageFormat class, are sufficient -for our needs. -<p>Entries in the properties file must follow the pattern: <font face="Courier New,Courier"><font size=-1><string><2-digit -suffix></font></font>. -<p>Entries should be ordered in the properties file alphabetically by key. -<p>Entries in the properties file must never be changed. If a code -change requires a message change, don't change the existing message; instead -create a new entry, incrementing the 2-digit suffix. This must be -done for two reasons: 1. You don't know whether the message -is being used elsewhere. 2. So the translator only has to be -aware of, and translate, the new strings. Without this restriction, -every time translators are given the properties file to translate, they -would have to translate all strings all the time. -<ul> </ul> -We may occasionally want to trim the properties file of old data, but this -should only be done on major releases. -<ul> </ul> +<br> +<li> +java.text.MessageFormat substitutes variables for +markers in the message text. +Markers use the syntax +<font face="Courier New,Courier">"{X}"</font> +where <code>X</code> is +the number of the variable, starting at 0. +</li> +</ul> + +<p>For example: <code>myMsg00=My {0} is {1}.</code> + +<p>Translation requires creating an +alternate version of the property file provided by AXIS +for a target language. +The JavaDoc for <code>java.utils.ResourceBundle</code> +provides details on how to identify different property +files for different locales. + +<p>For details on using AXIS's internationalization tools, +see the <a href="developers-guide.html">Developer's Guide</a>. +<br> <li> Default behavior</li> @@ -390,26 +360,104 @@ <br>The default behavior, meaning what happens when a translated file doesn't exist for a given locale, is to fall back on the English-language properties file. If that file doesn't exist (unlikely unless something is seriously -wrong), AXIS with throw an exception with an English-language reason message. +wrong), AXIS will throw an exception with an English-language reason message. <br> +</ul> + +<h4> +<a NAME="Extending Message Files"></a>Extending Message Files</h4> +AXIS provides a Message file extension mechanism +that allows AXIS-based code to use AXIS message keys, +as well as new message keys unique to the extended code. + +<ul> <li> -Examples</li> +Justification/Rationale</li> +<br> +AXIS provides pluggable interfaces for +various AXIS entities, including EngineConfigurationFactory's, +Provides, and Handlers. +AXIS also provides a variety of implementations +of these entities. +It is convenient to use AXIS source code for +such implementations as starting points for developing +extentions and customizations that fulfill the unique needs +of the end user. +<br> -<br>In <font face="Courier New,Courier"><font size=-1>org.apache.axis.client.Call.invoke</font></font>, -there is the following statement: -<p><font face="Courier New,Courier"><font size=-1> -if ( operationName == null )</font></font> -<br><font face="Courier New,Courier"><font size=-1> -throw new AxisFault( "No operation name specified" );</font></font> -<p>We will have to add an entry into org/apache/axis/i18n/resource.properties. -Something like: -<p><font face="Courier New,Courier"><font size=-1>noOperation=No operation -name specified.</font></font> -<p>And change the code to read: -<p><font face="Courier New,Courier"><font size=-1> -if ( operationName == null )</font></font> -<br><font face="Courier New,Courier"><font size=-1> -throw new AxisFault(JavaUtils.getMessage("noOperation"));</font></font></ul> +<li> +Procedure</li> +<br>To extend the AXIS message file: +<br> +<ul> +<li>Copy the AXIS source file +<code>java/src/org/apache/axis/i18n/Messages.java</code> +to your project/package, say +<code>my/project/package/path/Messages.java</code>. +</li> +<ul> +<li>Set the <code>package</code> declaration in the copied file +to the correct package name. +</li> +<li>Set the private attribute <code>projectName</code> +to <code>"my.project"</code>: +the portion of the package name that is common to your project. +<code>projectName</code> must be equal to or be a prefix of the +copied Messages package name. +</li> +</ul> +<br> +<li>Create the file +<code>my/project/package/path/resource.properties</code>. +Add new message key/value pairs to this file. +</li> +<br> +<li>As you copy AXIS source files over to your project, +change the <code>import org.apache.axis.i18n.Messages</code> +statement to <code>import my.project.package.path.Messages</code>. +</li> +<li>Use the methods provided by the class Messages, +as discussed in the <a href="developers-guide.html">Developer's Guide</a>, +to access the new messages. +</li> +</ul> +<br> + +<li> +Behavior</li> + +<ul> +<li> +Local Search</li> +<br><code>Messages</code> begins looking for a key's value in +the <code>resources.properties</code> +resource in it's (Messages) package. +<br> + +<li> +Hierarchical Search</li> +<br>If <code>Messages</code> cannot locate +either the key, or the resource file, +it walks up the package hierarchy until it finds it. +The top of the hierarchy, above which it will not search, +is defined by the <code>projectName</code> attribute, +set above. +<br> + +<li> +Default behavior</li> +<br>If the key cannot be found in the package hierarchy +then a default resource is used. +The default behaviour is determined by +the <code>parent</code> attribute of the +<code>Messages</code> class copied to your extensions directory. +<p>Unless changed, the default behavior, meaning what happens when a key +isn't defined in the new properties file, +is to fall back to the AXIS properties file +(org.apache.axis.i18n.resource.properties). +<br> +</ul> +</ul> <h3> <a NAME="Performance Monitoring Plug"></a>Performance Monitoring</h3>