version 1.5, 2003/10/13 21:18:22
|
version 1.9, 2007/01/24 21:24:43
|
|
|
</head> | </head> |
<body text="#000000" bgcolor="#ffffff" link="#0000ef" vlink="#55188a" | <body text="#000000" bgcolor="#ffffff" link="#0000ef" vlink="#55188a" |
alink="#ff0000"> | alink="#ff0000"> |
<center><font size="+4">Globalization HOWTO</font> |
<center> |
|
<p><big><big><big>Globalization HOWTO</big></big></big></p> |
<p>Release: Pegasus 2.3 </p> | <p>Release: Pegasus 2.3 </p> |
<p>Author: Chuck Carmack (carmack@us.ibm.com) </p> | <p>Author: Chuck Carmack (carmack@us.ibm.com) </p> |
<p>July 28, 2003</p> |
<p>December 1, 2003</p> |
</center> | </center> |
<p><br> | <p><br> |
|
Change History:<br> |
|
</p> |
|
<table cellpadding="2" cellspacing="2" border="1" |
|
style="text-align: left; width: 100%; margin-left: auto; margin-right: auto;"> |
|
<tbody> |
|
<tr> |
|
<td style="vertical-align: top;">01/12/03<br> |
|
</td> |
|
<td style="vertical-align: top;">carmack<br> |
|
</td> |
|
<td style="vertical-align: top;">Section 2.2.2. Changed how |
|
the package name parameter should be used. It should no longer be |
|
used as part of the table name inside the bundle.<br> |
|
</td> |
|
</tr> |
|
<tr> |
|
<td style="vertical-align: top;">08/04/06<br> |
|
</td> |
|
<td style="vertical-align: top;">Marek Szermutzky<br> |
|
</td> |
|
<td style="vertical-align: top;">Section 2.2.5. Added information how to write platform specific messages.<br> |
|
</td> |
|
</tr> |
|
<tr> |
|
<td style="vertical-align: top;">01/23/07<br> |
|
</td> |
|
<td style="vertical-align: top;">Sushma Fernandes<br> |
|
</td> |
|
<td style="vertical-align: top;">Section 2.2.5. Added information on special considerations while creating a new message.<br> |
|
</td> |
|
</tr> |
|
</tbody> |
|
</table> |
|
<p><br> |
</p> | </p> |
<h2> 1.0 Introduction</h2> | <h2> 1.0 Introduction</h2> |
<p><br> | <p><br> |
|
|
locale-neutral. In other words, the program should be able to run | locale-neutral. In other words, the program should be able to run |
in any locale without change. There are several categories in a | in any locale without change. There are several categories in a |
locale, including the language of message strings, date format, time | locale, including the language of message strings, date format, time |
format, etc. For release 2.3, the Pegasus server is concerned |
format, etc. For release 2.3, the Pegasus server is concerned with |
with the language of the message strings it returns to its clients. <br> |
the language of the message strings it returns to its clients. <br> |
</p> | </p> |
<p>To support internationalization, a program is designed to do the | <p>To support internationalization, a program is designed to do the |
following: <br> | following: <br> |
|
|
and usually has converters on the platform, it is a good choice for the | and usually has converters on the platform, it is a good choice for the |
'normalized' internal character set. The most | 'normalized' internal character set. The most |
'interoperable' solution for external data is to support UTF-8 (eg. | 'interoperable' solution for external data is to support UTF-8 (eg. |
network and file system data). The internal data is usually |
network and file system data). The internal data is usually UTF-16 |
UTF-16 (or UCS-2, but that is deprecated).</li> |
(or UCS-2, but that is deprecated).</li> |
<br> | <br> |
<li> Extract locale-sensitive resources, such as message | <li> Extract locale-sensitive resources, such as message |
strings, from the code to external resource files. Typically, the | strings, from the code to external resource files. Typically, the |
|
|
files.</li> | files.</li> |
<br> | <br> |
<li> APIs were added for clients to associate a language with | <li> APIs were added for clients to associate a language with |
the CIM objects they are sending to Pegasus. Also, APIs were |
the CIM objects they are sending to Pegasus. Also, APIs were added |
added for clients to determine the language of the error message or CIM |
for clients to determine the language of the error message or CIM |
object that Pegasus returns.</li> | object that Pegasus returns.</li> |
<br> | <br> |
<li> APIs were added for providers to determine the language of | <li> APIs were added for providers to determine the language of |
CIM objects sent by the client. Also, APIs were added for | CIM objects sent by the client. Also, APIs were added for |
providers to associate a language with the CIM object, or error |
providers to associate a language with the CIM object, or error message, |
message, they return to the client.</li> |
they return to the client.</li> |
</ul> | </ul> |
<p><br> | <p><br> |
Please refer to PEPs 56 and 58 for details about the globalization | Please refer to PEPs 56 and 58 for details about the globalization |
|
|
<li> The Pegasus 2.2 methods that take a char *, or return char *, are | <li> The Pegasus 2.2 methods that take a char *, or return char *, are |
unchanged. Code written to Pegasus 2.2 may have expected to store | unchanged. Code written to Pegasus 2.2 may have expected to store |
8-bit ASCII (ISO-8859-1) characters into String. These methods | 8-bit ASCII (ISO-8859-1) characters into String. These methods |
will convert the input to UTF-16 from 8-bit ASCII. (This is |
will convert the input to UTF-16 from 8-bit ASCII. (This is simple |
simple because UTF-16 is a superset of 8-bit ASCII - simply need to |
because UTF-16 is a superset of 8-bit ASCII - simply need to prepend |
prepend '\0' to each char). The Pegasus 2.2 methods that return |
'\0' to each char). The Pegasus 2.2 methods that return char data |
char data will attempt to convert from the UTF-16 internal |
will attempt to convert from the UTF-16 internal representation to |
representation to 8-bit ASCII. Characters that cannot be |
8-bit ASCII. Characters that cannot be converted will be replaced |
converted will be replaced with a substitution character.</li> |
with a substitution character.</li> |
<br> | <br> |
<li> All methods that take or return Char16 data are | <li> All methods that take or return Char16 data are |
unchanged. The String class now supports UTF-16 data in Char16, | unchanged. The String class now supports UTF-16 data in Char16, |
although surrogate pairs will require two consecutive Char16 | although surrogate pairs will require two consecutive Char16 |
objects. The String class does NO checking for unmatched |
objects. The String class does NO checking for unmatched surrogate |
surrogate pairs.</li> |
pairs.</li> |
<br> | <br> |
<li> New methods have been added to take and return UTF-8 | <li> New methods have been added to take and return UTF-8 |
data. The String class will convert between UTF-8 and the UTF-16 | data. The String class will convert between UTF-8 and the UTF-16 |
internal representation as needed. These new methods will use |
internal representation as needed. These new methods will use char |
char * parameters, but will be clearly labelled as UTF-8 methods.</li> |
* parameters, but will be clearly labelled as UTF-8 methods.</li> |
<br> | <br> |
| |
</ul> | </ul> |
|
|
superset of 8-bit ASCII. Any String object containing EBCDIC data | superset of 8-bit ASCII. Any String object containing EBCDIC data |
will not work if it is used by Pegasus to read or write data from | will not work if it is used by Pegasus to read or write data from |
external sources, such as the network or repository files. In | external sources, such as the network or repository files. In |
other words, any String containing EBCDIC data should not leave the |
other words, any String containing EBCDIC data should not leave the code |
code using it. <br> |
using it. <br> |
<br> | <br> |
| |
<h3> 2.2 Localization Support</h3> | <h3> 2.2 Localization Support</h3> |
|
|
</p> | </p> |
<p>CIM clients may use the Accept-Language HTTP header to specify the | <p>CIM clients may use the Accept-Language HTTP header to specify the |
languages they wish to be returned in the CIM response message. | languages they wish to be returned in the CIM response message. |
CIM clients may also use the Content-Language header to tag the |
CIM clients may also use the Content-Language header to tag the language |
language of any CIM objects they are sending to the server in the CIM |
of any CIM objects they are sending to the server in the CIM request |
request message. The server, and providers, should attempt to |
message. The server, and providers, should attempt to return |
return error messages and CIM objects in one of the accept languages |
error messages and CIM objects in one of the accept languages requested |
requested by the client. The server and providers should set the |
by the client. The server and providers should set the |
Content-Language header in the CIM response message to indicate which |
Content-Language header in the CIM response message to indicate which of |
of the requested languages they are returning. <br> |
the requested languages they are returning. <br> |
</p> | </p> |
<p>NOTE: Localization support was not added for the MOF files and | <p>NOTE: Localization support was not added for the MOF files and |
repository in Pegasus 2.3. The #pragma locale, #pragma | repository in Pegasus 2.3. The #pragma locale, #pragma |
|
|
classes, qualifiers, and instances stored in the repository are not | classes, qualifiers, and instances stored in the repository are not |
tagged with a language. The Accept-Language and Content-Language | tagged with a language. The Accept-Language and Content-Language |
headers will be ignored for repository operations. However, since | headers will be ignored for repository operations. However, since |
the repository will support UTF-8, characters for any language |
the repository will support UTF-8, characters for any language may |
may be stored there. <br> |
be stored there. <br> |
</p> | </p> |
<p>NOTE: Since the Content-Language header applies to the entire | <p>NOTE: Since the Content-Language header applies to the entire |
HTTP message, it applies to the entire CIM-XML document. This | HTTP message, it applies to the entire CIM-XML document. This |
|
|
remain until the CIM standard has been updated to support language tags | remain until the CIM standard has been updated to support language tags |
tied to individual CIM values. From the client perspective, it is | tied to individual CIM values. From the client perspective, it is |
possible for Pegasus to send a CIM response with NO Content-Language, | possible for Pegasus to send a CIM response with NO Content-Language, |
even if the client had sent Accept-Language. This can |
even if the client had sent Accept-Language. This can happen |
happen if Pegasus does not know the language of the response. An |
if Pegasus does not know the language of the response. An example |
example is a request that was sent to a Pegasus 2.2 provider. |
is a request that was sent to a Pegasus 2.2 provider. Another |
Another example is an enumerated response where each provider returned |
example is an enumerated response where each provider returned a |
a different language. Please refer to PEP58 for details on these |
different language. Please refer to PEP58 for details on these |
provider scenarios. <br> | provider scenarios. <br> |
</p> | </p> |
<p>Pegasus 2.3 has added classes for the localization support. |
<p> |
There are new classes called AcceptLanguages and ContentLanguages that |
The Accept-Language and Content-Language headers are encapsulated |
encapsulate the Accept-Language and Content-Language headers, |
in AcceptLanguageList and ContentLanguageList classes, respectively. |
respectively. These classes are basically containers of |
These classes contain LanguageTag objects. The AcceptLanguageList class |
AcceptLanguageElement and ContentLanguageElement, where a language |
keeps its LanguageTags prioritized based on quality, |
element represents one language tag. The AcceptLanguages class |
|
will keep the AcceptLanguageElement's prioritized based on quality, |
|
according to RFC 2616. <br> | according to RFC 2616. <br> |
</p> | </p> |
<p>AcceptLanguages and ContentLanguages are the objects used by code |
<p>AcceptLanguageList and ContentLanguageList are the objects used by code |
throughout the request/response processing, from the client to the | throughout the request/response processing, from the client to the |
server to the providers and back. The server handles the creation | server to the providers and back. The server handles the creation |
of these objects from the HTTP headers. Code at each point in the | of these objects from the HTTP headers. Code at each point in the |
process will have access to these objects. <br> | process will have access to these objects. <br> |
</p> | </p> |
<p>Please refer to the following files for details on the new Pegasus |
<p>Please refer to the following files for details on the Pegasus |
classes. <br> |
language interfaces.<br> |
</p> | </p> |
<ul> | <ul> |
<li> pegasus/src/Pegasus/Common/AcceptLanguages.h</li> |
<li> pegasus/src/Pegasus/Common/AcceptLanguageList.h</li> |
<li> pegasus/src/Pegasus/Common/AcceptLanguageElement.h</li> |
<li> pegasus/src/Pegasus/Common/ContentLanguageList.h</li> |
<li> pegasus/src/Pegasus/Common/ContentLanguages.h</li> |
<li> pegasus/src/Pegasus/Common/LanguageTag.h</li> |
<li> pegasus/src/Pegasus/Common/ContentLanguageElement.h</li> |
|
<li> pegasus/src/Pegasus/Common/LanguageElementContainer.h</li> |
|
<li> pegasus/src/Pegasus/Common/LanguageElement.h</li> |
|
</ul> | </ul> |
<p><br> | <p><br> |
See the sections below for details on how to write clients and | See the sections below for details on how to write clients and |
|
|
href="http://oss.software.ibm.com/icu/userguide/ResourceManagement.html">Resource | href="http://oss.software.ibm.com/icu/userguide/ResourceManagement.html">Resource |
Management</a> section of the <a | Management</a> section of the <a |
href="http://oss.software.ibm.com/icu/userguide/">ICU User Guide</a> | href="http://oss.software.ibm.com/icu/userguide/">ICU User Guide</a> |
. This section will tell you how to <br> |
. This section will tell you how to create and organize your |
create and organize your resource bundles for different |
resource bundles for different languages. Note: your |
languages. Note: your resource bundles should be organized |
resource bundles should be organized in a tree structure similiar to |
in a tree structure similiar to the one shown in the Resource |
the one shown in the Resource Management section, including the empty |
Management section, including the empty bundles in the tree. It |
bundles in the tree. <br> |
is recommended that you ship a root resource bundle to be used as the |
</p> |
fallback in case the client requests a language that you are not |
<p><br> |
|
It is recommended that you ship a root resource bundle to be used as |
|
the fallback in case the client requests a language that you are not |
supporting. The Pegasus make files are set up to automatically | supporting. The Pegasus make files are set up to automatically |
create and compile a root resource bundle for you. For Pegasus | create and compile a root resource bundle for you. For Pegasus |
2.3, the make will use your "en" bundle, upper case all the messages, | 2.3, the make will use your "en" bundle, upper case all the messages, |
and then put the uppercased messages into the root bundle. The | and then put the uppercased messages into the root bundle. The |
uppercasing of the messages is necessary to create a "fallback" root | uppercasing of the messages is necessary to create a "fallback" root |
bundle that contains invariant characters across all EBCIC and |
bundle that contains invariant characters across all EBCDIC and |
ASCII codepages. <br> | ASCII codepages. <br> |
</p> | </p> |
<p>NOTE: When creating your resource bundles, the name of the | <p>NOTE: When creating your resource bundles, the name of the |
table resource should contain the package name. For |
table resource should <span style="font-style: italic;">not</span> |
example, if you have a bundle with a package name of "xyz", then the |
contain the package name. For example, if you <br> |
"en" bundle should start like this: </p> |
have a bundle with a package name of "xyz", then the "en" bundle should |
<p>xyz_en:table { <br> |
start like this: </p> |
|
<p><br> |
|
en:table { <br> |
..... messages here <br> | ..... messages here <br> |
| |
} <br> |
}</p> |
</p> |
|
<p><i>not</i> like this: </p> | <p><i>not</i> like this: </p> |
<p>en:table { <br> |
<p>xyz_en:table { <br> |
..... messages here <br> | ..... messages here <br> |
| |
} </p> |
} <br> |
<p>This is different than some of the examples in the <a |
<br> |
href="http://oss.software.ibm.com/icu/userguide/ResourceManagement.html">Resource |
</p> |
Management</a> section, but is needed because the -p option is not used |
<p>This is needed because the package name (-p) option is used by the |
on genrb by the make files. <br> |
Pegasus make files on the call to genrb. <br> |
</p> | </p> |
<p>NOTE: Pegasus 2.3 only supports simple string resources in the | <p>NOTE: Pegasus 2.3 only supports simple string resources in the |
ICU resource bundles. String resources may only be loaded by | ICU resource bundles. String resources may only be loaded by |
|
|
<p><br> | <p><br> |
Code that needs to load a message in Pegasus does not call ICU | Code that needs to load a message in Pegasus does not call ICU |
directly. Two message loading classes were added for Pegasus | directly. Two message loading classes were added for Pegasus |
2.3: MessageLoader and MessageLoaderParms. These classes |
2.3: MessageLoader and MessageLoaderParms. These classes are |
are abstractions designed to hide of the actual loader used (but note |
abstractions designed to hide of the actual loader used (but note that |
that at the time of writing, only ICU is supported). The |
at the time of writing, only ICU is supported). The |
MessageLoader is used to load a message using a list of preferrred | MessageLoader is used to load a message using a list of preferrred |
languages. The parameters to MessageLoader are encapsulated in a | languages. The parameters to MessageLoader are encapsulated in a |
MessageLoaderParms object. <br> | MessageLoaderParms object. <br> |
</p> | </p> |
<p>The MessageLoader is the place where the Accept-Language header, | <p>The MessageLoader is the place where the Accept-Language header, |
Content-Language header, and the ICU resource bundles, join up. | Content-Language header, and the ICU resource bundles, join up. |
The MessageLoader class is designed to receive an AcceptLanguages |
The MessageLoader class is designed to receive an AcceptLanguageList |
object, and a set of parameters indicating the bundle base-name and | object, and a set of parameters indicating the bundle base-name and |
message ID to use. The AcceptLanguages object contains the list |
message ID to use. The AcceptLanguageList object contains the list of |
of requested languages sent by the client. The MessageLoader |
requested languages sent by the client. The MessageLoader |
searches for the message in the set of bundles named with the |
searches for the message in the set of bundles named with the base-name, |
base-name, using the AcceptLanguages for the list of specific |
using the AcceptLanguageList for the list of specific translated bundles |
translated bundles to search. The MessageLoader returns the |
to search. The MessageLoader returns the message that it found, |
message that it found, along with a ContentLanguages object indicating |
along with a ContentLanguageList object indicating the language of the |
the language of the message. The ContentLanguages object should |
message. The ContentLanguageList object should be used to indicate |
be used to indicate the language of the response sent back to the |
the language of the response sent back to the client. <br> |
client. <br> |
|
</p> | </p> |
<p>The MessageLoaderParms object contains the parameters to load the | <p>The MessageLoaderParms object contains the parameters to load the |
message. There are many parameters, but many can be allowed to | message. There are many parameters, but many can be allowed to |
|
|
<td>Input. <br> | <td>Input. <br> |
Optional <br> | Optional <br> |
Default: $PEGASUS_HOME/msg/pegasus/pegasusServer</td> | Default: $PEGASUS_HOME/msg/pegasus/pegasusServer</td> |
<td>Path to the root resource bundle file which contains the |
<td>Path to the resource bundle file which contains the |
msg_id. <br> | msg_id. <br> |
Note: Only specify the path down to the bundle base-name. Do not | Note: Only specify the path down to the bundle base-name. Do not |
append a language tag, such as "_root" or "_en". Do not append a | append a language tag, such as "_root" or "_en". Do not append a |
|
|
Note: defaults to the bundle containing the Pegasus server messages.</td> | Note: defaults to the bundle containing the Pegasus server messages.</td> |
</tr> | </tr> |
<tr> | <tr> |
<td>AcceptLanguages acceptlanguages;</td> |
<td>AcceptLanguageList acceptlanguages;</td> |
<td>Input. <br> | <td>Input. <br> |
Optional <br> | Optional <br> |
Default: AcceptLanguages::EMPTY</td> |
Default: AcceptLanguageList()</td> |
<td>Contains the list of preferred languages, in priority | <td>Contains the list of preferred languages, in priority |
order. This is combined with msg_src_path to determine which | order. This is combined with msg_src_path to determine which |
resource bundles to search for for the msg_id. If not |
resource bundles to search for for the msg_id. If not empty, |
empty, overrides useThreadLocale and useProcessLocale.</td> |
overrides useThreadLocale and useProcessLocale.</td> |
</tr> | </tr> |
<tr> | <tr> |
<td>ContentLanguages contentlanguages;</td> |
<td>ContentLanguageList contentlanguages;</td> |
<td>Output</td> | <td>Output</td> |
<td>Contains the language that MessageLoader found for the | <td>Contains the language that MessageLoader found for the |
msg_id. </td> | msg_id. </td> |
|
|
<td>Input <br> | <td>Input <br> |
Optional <br> | Optional <br> |
Default = <font color="#ff0000">true</font></td> | Default = <font color="#ff0000">true</font></td> |
<td>If true, MessageLoader will use the AcceptLanguages set by |
<td>If true, MessageLoader will use the AcceptLanguageList set by |
Pegasus into the caller's Thread. See the Note below for | Pegasus into the caller's Thread. See the Note below for |
details. </td> | details. </td> |
</tr> | </tr> |
|
|
Default = false</td> | Default = false</td> |
<td>If true, use ICU's fallback mechnism to search more general | <td>If true, use ICU's fallback mechnism to search more general |
resource bundles if the msg_id cannot be found. Note: the | resource bundles if the msg_id cannot be found. Note: the |
recommended setting is false if you are using an AcceptLanguages from a |
recommended setting is false if you are using an AcceptLanguageList from a |
CIM client. The Accept-Languages HTTP header from the client | CIM client. The Accept-Languages HTTP header from the client |
contains the fallback specifications.</td> |
contains the fallback specifications. Using ICU's fallback in this |
|
case may lead to returning a language that the client didn't ask for.</td> |
</tr> | </tr> |
<tr> | <tr> |
<td>Formatter::Arg arg0; <br> | <td>Formatter::Arg arg0; <br> |
|
|
<p>Notes: <br> | <p>Notes: <br> |
</p> | </p> |
<p>The "useThreadLocale" parameter defaults to true. This flag | <p>The "useThreadLocale" parameter defaults to true. This flag |
indicates to use the AcceptLanguages object set by Pegasus into the |
indicates to use the AcceptLanguageList object set by Pegasus into the |
Pegasus Thread in which the caller's code is running. This | Pegasus Thread in which the caller's code is running. This |
AcceptLanguages object reflects the languages requested by the |
AcceptLanguageList object reflects the languages requested by the |
client. This is useful for code that may not have access to the | client. This is useful for code that may not have access to the |
AcceptLanguages from the client. Pegasus sets this |
AcceptLanguageList from the client. Pegasus sets this AcceptLanguageList |
AcceptLanguages object into the Thread of providers and internal |
object into the Thread of providers and internal Pegasus code. |
Pegasus code. For this reason, it is recommended that provider |
For this reason, it is recommended that provider and internal Pegasus |
and internal Pegasus code use the "useThreadLocale" flag instead of |
code use the "useThreadLocale" flag instead of explicity passing in an |
explicity passing in an AcceptLanguages object. See the Provider |
AcceptLanguageList object. See the Provider Developer and Pegasus |
Developer and Pegasus Developer sections for details. <br> |
Developer sections for details. <br> |
</p> | </p> |
<p>The "useProcessLocale" flag can be used to tell MessageLoader to use | <p>The "useProcessLocale" flag can be used to tell MessageLoader to use |
the default locale of the process, as determined by ICU. This is | the default locale of the process, as determined by ICU. This is |
useful for situations where the caller is not localizing for a client | useful for situations where the caller is not localizing for a client |
request. The caller may itself be a client (eg. cimconfig), or |
request. The caller may itself be a client (eg. cimconfig), or may |
may need to log messages to the system log in the locale of the Pegasus |
need to log messages to the system log in the locale of the Pegasus |
server process. See the CLI Messages and Logger Messages sections | server process. See the CLI Messages and Logger Messages sections |
below. <br> | below. <br> |
</p> | </p> |
<p>"Master switch" <br> | <p>"Master switch" <br> |
The MessageLoader class has a public static Boolean variable called | The MessageLoader class has a public static Boolean variable called |
_useProcessLocale that may be used to override all the AcceptLanguages |
_useProcessLocale that may be used to override all the AcceptLanguageList |
and useThreadLocale settings in the MessageLoaderParms objects passed | and useThreadLocale settings in the MessageLoaderParms objects passed |
in. This is useful for CLI code (eg cimconfig) that needs to | in. This is useful for CLI code (eg cimconfig) that needs to |
localize its messages based on the locale of its process, which refects | localize its messages based on the locale of its process, which refects |
the locale set by the user running the CLI (eg. $LANG on Unix). | the locale set by the user running the CLI (eg. $LANG on Unix). |
The CLI code may call Pegasus APIs that are coded to use the Thread's | The CLI code may call Pegasus APIs that are coded to use the Thread's |
AcceptLanguages, which will not be set in this case. The |
AcceptLanguageList, which will not be set in this case. The |
_useProcessLocale static variable tells the MessageLoader to ignore the | _useProcessLocale static variable tells the MessageLoader to ignore the |
AcceptLanguages, useThreadLocale, and useProcessLocale settings in |
AcceptLanguageList, useThreadLocale, and useProcessLocale settings in |
MessageLoaderParms that it gets. The MessageLoader will use the | MessageLoaderParms that it gets. The MessageLoader will use the |
default process locale, as determined by ICU, in this case. <br> | default process locale, as determined by ICU, in this case. <br> |
</p> | </p> |
|
|
the "fallback" mechanism described in the ICU Resource Management | the "fallback" mechanism described in the ICU Resource Management |
section. This is because the Accept-Language header itself | section. This is because the Accept-Language header itself |
describes the fallback that the client wants. However, the | describes the fallback that the client wants. However, the |
MessageLoader does "fallback" to the root resource bundle if none of |
MessageLoader does "fallback" to the root resource bundle if none of the |
the languages in AcceptLanguages can be found. If the root |
languages in AcceptLanguageList can be found. If the root resource |
resource bundle cannot be found, then the default_msg is |
bundle cannot be found, then the default_msg is returned. The |
returned. The "useICUFallback" flag can be set to have |
"useICUFallback" flag can be set to have MessageLoader use ICU fallback |
MessageLoader use ICU fallback on all message load attempts. |
on all message load attempts. However, usage of this flag for |
However, usage of this flag for client requests may lead to incorrect |
client requests may lead to incorrect results. For example, a |
results. For example, a client sets Accept-Language to french, |
client sets Accept-Language to french, german, and spanish, in that |
german, and spanish, in that order, but there is no french resource |
order, but there is no french resource bundle. A call to |
bundle. A call to MessageLoader with useICUfallback == true would |
MessageLoader with useICUfallback == true would cause the root resource |
cause the root resource bundle string to be returned on the attempt to |
bundle string to be returned on the attempt to load from the french |
load from the french bundle. But the client requested german to |
bundle. But the client requested german to be the fallback after |
be the fallback after french. <br> |
french. <br> |
</p> | </p> |
<p>Please refer to the following files for details on the new Pegasus | <p>Please refer to the following files for details on the new Pegasus |
classes. <br> | classes. <br> |
|
|
classes described above. Note: this a generic example. Each | classes described above. Note: this a generic example. Each |
of the developer sections below have 'real-life' examples that are | of the developer sections below have 'real-life' examples that are |
better suited to each type of code. </p> | better suited to each type of code. </p> |
<p>// Build an AcceptLanguages with some language elements <br> |
<p>// Build an AcceptLanguageList with some language elements <br> |
AcceptLanguages acceptLangs; <br> |
AcceptLanguageList acceptLangs; <br> |
acceptLangs.add(AcceptLanguageElement("fr", 0.5)); <br> |
acceptLangs.insert(LanguageTag("fr"), 0.5); <br> |
acceptLangs.add(AcceptLanguageElement("de", 0.8)); <br> |
acceptLangs.insert(LanguageTag("de"), 0.8); <br> |
acceptLangs.add(AcceptLanguageElement("es", 0.4)); </p> |
acceptLangs.insert(LanguageTag("es"), 0.4); </p> |
<p>// Construct a MessageLoaderParms <br> | <p>// Construct a MessageLoaderParms <br> |
MessageLoaderParms parms("msgID", "default message"); <br> | MessageLoaderParms parms("msgID", "default message"); <br> |
parms. msg_src_path = "/my_msg_dir/my_bundle"; <br> | parms. msg_src_path = "/my_msg_dir/my_bundle"; <br> |
|
|
String localizedMsg = MessageLoader::getMessage(parms); <br> | String localizedMsg = MessageLoader::getMessage(parms); <br> |
<br> | <br> |
</p> | </p> |
<h4> 2.2.4 Message Writing Guidelines</h4> |
<h4> 2.2.5 Message Writing Guidelines</h4> |
<p><br> | <p><br> |
Here are some basic rules for writing messages: <br> | Here are some basic rules for writing messages: <br> |
</p> | </p> |
<ul> | <ul> |
<li> If you want to claim that you are globalized, no hardcoded | <li> If you want to claim that you are globalized, no hardcoded |
messages!</li> | messages!</li> |
<li> Avoid combining messages in the code from other messages. |
<li> Avoid creating a message in the code by combining other |
When you do this you are assuming that you know the grammar for every |
messages. When you do this you are assuming that you know the |
language.</li> |
grammar for every language.</li> |
<li> String substitutions into messages are generally untranslated, | <li> String substitutions into messages are generally untranslated, |
ie. not loaded from the resource bundle. Example: a file | ie. not loaded from the resource bundle. Example: a file |
name.</li> | name.</li> |
|
|
ultimately the customer.</li> | ultimately the customer.</li> |
<li> <b>TODO </b>- find a good message writing guide to link to</li> | <li> <b>TODO </b>- find a good message writing guide to link to</li> |
</ul> | </ul> |
|
|
|
<p><b>When do I create a new message ?</b></p> |
|
|
|
<p>A new message should be created if a message is needed with a content not |
|
described by any existing message.</p> |
|
|
|
<p>A new message should be created if the number or placement of substitution |
|
parameters of an existing message would require an update.</p> |
|
|
|
<p>It is not necessary to create a new message if just the text of the message |
|
is changed, while the meaning is kept. For instance if the |
|
event(error,warning,whatever) is described more precisely by the new message |
|
text, it is not necessary to create a new message, but the existing one should |
|
be updated.</p> |
|
|
|
<p><b>Are there any special considerations while creating a new message ? </b></p> |
|
|
|
<ul> |
|
<li>If a message definition contains text within a single quote |
|
it is not interpreted in any way. |
|
|
|
<p><i>Example:</i></p> |
|
<p> Server.CIMOperationRequestAuthorizer.NOT_IN_AUTHORIZED_GRP: |
|
string {"PGS05202: User '{0}' is not authorized to access CIM data."} |
|
</p> |
|
|
|
<p><i>Processed message:</i></p> |
|
<p> User {0} is not authorized to access CIM data. </p> |
|
</li> |
|
|
|
<li> For a single quote to appear in a processed message, it needs to be preceded by |
|
another single quote. |
|
|
|
<p><i>Example:</i></p> |
|
<p> Server.CIMOperationRequestAuthorizer.NOT_IN_AUTHORIZED_GRP: |
|
string {"PGS05202: User ''{0}'' is not authorized to access CIM data."} |
|
</p> |
|
|
|
<p><i>Processed message:</i></p> |
|
<p> User 'wbemuser' is not authorized to access CIM data. </p> |
|
</li> |
|
|
|
<li> For a double quote to appear in a processed message, it needs to be preceded by |
|
a back slash. |
|
|
|
<p><i>Example:</i></p> |
|
<p> |
|
ControlProviders.ProviderRegistrationProvider.ProviderRegistrationProvider. |
|
UNSUPPORTED_USERCONTEXT_VALUE:string {"PGS03029: Unsupported UserContext |
|
value: \"{0}\"."} |
|
</p> |
|
|
|
<p><i>Processed message:</i></p> |
|
<p> Unsupported UserContext value: "10". </p> |
|
</li> |
|
</ul> |
|
|
|
<p> </p> |
|
|
|
<p><b>How do I write a platform specific |
|
message ? </b></p> |
|
|
|
<p>Platform specific messages generate in a non-platform specific source file |
|
should be formatted with a .<platform> or .STANDARD suffix.</p> |
|
|
|
<p><i>Example:</i></p> |
|
<p>Compiler.cmdline.cimmof.cmdline.MENU.PEGASUS_OS_HPUX</p> |
|
<p>Compiler.cmdline.cimmof.cmdline.MENU.PEGASUS_OS_OS40</p> |
|
<p>Compiler.cmdline.cimmof.cmdline.MENU.STANDARD</p> |
|
|
|
<p> </p> |
|
|
|
<p><b>Where should I place platform specific |
|
messages ? </b></p> |
|
|
|
<p>As described in the message bundle file pegasusServer_en.txt messages belong |
|
into the section corresponding the file they are created in. This does account |
|
the same to platform specific messages.</p> |
|
<p>If a message is generated inside a source file not specific to a single |
|
platform, the message should be part of the message bundle section of that |
|
source file.</p> |
|
<p>If a new platform specific message is generated inside a platform specific |
|
source file, the message belongs to the platform specific section of the |
|
message bundle file.</p> |
|
|
|
<p><i>Examples:</i></p> |
|
|
|
<p>ProviderManager.ProviderAgent.ProviderAgent.UNINITIALIZED_SECURITY_SETUP.PEGASUS_OS_ZOS |
|
- this message is and should be part of the section for the ProviderAgent as it |
|
is generated inside the provider agent and not a z/OS platform specific file</p> |
|
<p>Common.safCheckzOS_inline.BAD_WBEM_SECURITY_SETUP - this message does and |
|
should reside inside the platform specific section as the message is generated |
|
in a z/OS platform only file</p> |
|
|
|
<p> </p> |
|
|
<h4> 2.2.5 Localized Exceptions</h4> | <h4> 2.2.5 Localized Exceptions</h4> |
<p><br> | <p><br> |
The base Exception class, and derived classes, have been updated to | The base Exception class, and derived classes, have been updated to |
support localization. Constructors have been added that take a | support localization. Constructors have been added that take a |
MessageLoaderParms object. These constructors will use the | MessageLoaderParms object. These constructors will use the |
MessageLoaderParms object to call the MessageLoader to load the | MessageLoaderParms object to call the MessageLoader to load the |
localized exception message. The localized message is saved in |
localized exception message. The localized message is saved in the |
the Exception. The ContentLanguages object returned by |
Exception. The ContentLanguageList object returned by MessageLoader |
MessageLoader is also saved in the Exception. This indicates the |
is also saved in the Exception. This indicates the language of |
language of the message. The ContentLanguages object is used |
the message. The ContentLanguageList object is used later to set the |
later to set the Content-Language header in the HTTP message to the |
Content-Language header in the HTTP message to the client. <br> |
client. <br> |
|
</p> | </p> |
<p>The old Exception constructors that take a String will remain. | <p>The old Exception constructors that take a String will remain. |
These should be used in cases where the code throwing the exception is | These should be used in cases where the code throwing the exception is |
|
|
<ul> | <ul> |
<li> Are there localized string properties that need to be | <li> Are there localized string properties that need to be |
supported? If so, then the client will use Accept-Language to | supported? If so, then the client will use Accept-Language to |
request specific languages for these properties. If the |
request specific languages for these properties. If the properties |
properties are read-only, use MessageLoader to load the localized |
are read-only, use MessageLoader to load the localized strings for the |
strings for the properties.</li> |
properties.</li> |
<li> If you have a localized read/write string property, then the | <li> If you have a localized read/write string property, then the |
client will use Content-Language to set the property with an associated | client will use Content-Language to set the property with an associated |
language. The client will expect to be able to retrieve the | language. The client will expect to be able to retrieve the |
|
|
<ul> | <ul> |
<li> Pegasus will set the Accept-Language from the client into the | <li> Pegasus will set the Accept-Language from the client into the |
thread in which the provider is running. By using the | thread in which the provider is running. By using the |
useThreadLocale setting in MessageLoaderParms, providers can easily |
useThreadLocale setting in MessageLoaderParms, providers can easily load |
load strings using the client's requested Accept-Language. The |
strings using the client's requested Accept-Language. The |
provider does not need to know what the Accept-Language is. This | provider does not need to know what the Accept-Language is. This |
is the recommended method to load messages based on the client's |
is the recommended method to load messages based on the client's request.</li> |
request.</li> |
|
<br> | <br> |
<li> The OperationContext will contain an AcceptLanguages object |
<li> The OperationContext will contain an AcceptLanguageList object |
that has the Accept-Language requested by the client. The |
that has the Accept-Language requested by the client. The provider |
provider can use this AcceptLanguages object to load strings with |
can use this AcceptLanguageList object to load strings with MessageLoader.</li> |
MessageLoader.</li> |
|
</ul> | </ul> |
<p><br> | <p><br> |
The OperationContext will also contain a ContentLanguages object that |
The OperationContext will also contain a ContentLanguageList object that |
is set from the Content-Language in the client request. This is | is set from the Content-Language in the client request. This is |
the language of the CIM objects being passed to the provider on that | the language of the CIM objects being passed to the provider on that |
request. A localized provider should store the content language | request. A localized provider should store the content language |
|
|
returning by calling setContext( ) on the ResponseHandler. This | returning by calling setContext( ) on the ResponseHandler. This |
will be used to set the Content-Language in the CIM response message | will be used to set the Content-Language in the CIM response message |
sent back to the client. If setContext( ) is not called, then no | sent back to the client. If setContext( ) is not called, then no |
Content-Language will be returned to the client. setContext( ) |
Content-Language will be returned to the client. The setContext( ) |
should only be called once per response. <br> |
function should only be called once per response. <br> |
</p> | </p> |
<h3> 3.2 Sample Code</h3> | <h3> 3.2 Sample Code</h3> |
<p><br> | <p><br> |
|
|
| |
// We are going to let the message loader parameters default to use the <br> | // We are going to let the message loader parameters default to use the <br> |
| |
// AcceptLanguages that Pegasus set into our thread. <br> |
// AcceptLanguageList that Pegasus set into our thread. <br> |
| |
// (this equals the AcceptLanguages requested by the client) <br> |
// (this equals the AcceptLanguageList requested by the client) <br> |
| |
// Note: This parms object could be constructed once and <br> | // Note: This parms object could be constructed once and <br> |
| |
|
|
| |
// of parms to the language that it found for the message. <br> | // of parms to the language that it found for the message. <br> |
| |
ContentLanguages rtnLangs = parms.contentlanguages; </p> |
ContentLanguageList rtnLangs = parms.contentlanguages; </p> |
<p> | <p> |
// We need to tag the instance we are returning with the <br> | // We need to tag the instance we are returning with the <br> |
// the | // the |
|
|
| |
// We are going to let the message loader parameters default to use the <br> | // We are going to let the message loader parameters default to use the <br> |
| |
// AcceptLanguages that Pegasus set into our thread. <br> |
// AcceptLanguageList that Pegasus set into our thread. <br> |
| |
// (this equals the AcceptLanguages requested by the client) <br> |
// (this equals the AcceptLanguageList requested by the client) <br> |
| |
// Note: This parms object could be constructed once and <br> | // Note: This parms object could be constructed once and <br> |
| |
|
|
What happens if the client sets the read/write property with a | What happens if the client sets the read/write property with a |
Content-Language that is not one of the supported languages for the | Content-Language that is not one of the supported languages for the |
read/only property? This provider allows the client to set any | read/only property? This provider allows the client to set any |
language into the read/write property, and get that property back in |
language into the read/write property, and get that property back in the |
the same language. This becomes an issue when the client does a |
same language. This becomes an issue when the client does a |
getInstance( ) later, because the Content-Language on the returned | getInstance( ) later, because the Content-Language on the returned |
instance applies to all the properties. A related issue is what |
instance applies to all the properties. A related issue is what to |
to return for Content-Language when the client does enumerateInstances, |
return for Content-Language when the client does enumerateInstances, |
but the instances have different languages. Recall that | but the instances have different languages. Recall that |
Content-Language applies to the entire response (a limitation in the |
Content-Language applies to the entire response (a limitation in the CIM |
CIM specification). <br> |
specification). <br> |
</p> | </p> |
<p>NOTE: Indication Providers have other special considerations | <p>NOTE: Indication Providers have other special considerations |
for language support. Please refer to PEP58. <br> | for language support. Please refer to PEP58. <br> |
|
|
(SC41-5607-02). The Pegasus string literals will be compiled with | (SC41-5607-02). The Pegasus string literals will be compiled with |
the UTF-8 compile switch described in this section. OS/400 | the UTF-8 compile switch described in this section. OS/400 |
provider developers should strongly consider using the same compile | provider developers should strongly consider using the same compile |
switch for their string literals. This would allow the literals |
switch for their string literals. This would allow the literals to |
to match the UTF-8 encoding expected by the C-runtime.</li> |
match the UTF-8 encoding expected by the C-runtime.</li> |
</ul> | </ul> |
<h2> 4. 0 Client Developers</h2> | <h2> 4. 0 Client Developers</h2> |
<p><br> | <p><br> |
|
|
<p> // Language priority is martian, pig-latin, and | <p> // Language priority is martian, pig-latin, and |
french. We should <br> | french. We should <br> |
// get french back, even though its the lowest priority <br> | // get french back, even though its the lowest priority <br> |
AcceptLanguages acceptLangs; <br> |
AcceptLanguageList acceptLangs; <br> |
acceptLangs.add(AcceptLanguageElement("x-martian")); <br> |
acceptLangs.insert(LanguageTag("x-martian"), 1.0); <br> |
acceptLangs.add(AcceptLanguageElement("fr", 0.1)); <br> |
acceptLangs.insert(LanguageTag("fr"), 0.1); <br> |
acceptLangs.add(AcceptLanguageElement("x-pig-latin", 0.4)); </p> |
acceptLangs.insert(LanguageTag("x-pig-latin"), 0.4); </p> |
<p> // Set the requested languages into the CIMClient <br> | <p> // Set the requested languages into the CIMClient <br> |
client.setRequestAcceptLanguages(acceptLangs); </p> | client.setRequestAcceptLanguages(acceptLangs); </p> |
<p> // Get the instance <br> | <p> // Get the instance <br> |
|
|
| |
get(returnedString); </p> | get(returnedString); </p> |
<p> // Check that we got back french <br> | <p> // Check that we got back french <br> |
ContentLanguages CL_FR("fr"); <br> |
ContentLanguageList CL_FR(); <br> |
|
CL_FR.append(LanguageTag("fr")); <br> |
String expectedFRString = "oui"; <br> | String expectedFRString = "oui"; <br> |
PEGASUS_ASSERT(CL_FR == client.getResponseContentLanguages()); <br> | PEGASUS_ASSERT(CL_FR == client.getResponseContentLanguages()); <br> |
PEGASUS_ASSERT(expectedFRString == returnedString); </p> | PEGASUS_ASSERT(expectedFRString == returnedString); </p> |
|
|
ICU. If ICU is installed on the client system then CIMClient will | ICU. If ICU is installed on the client system then CIMClient will |
set the Accept-Language from the default ICU process locale. If | set the Accept-Language from the default ICU process locale. If |
ICU is not installed then the caller is required to set an | ICU is not installed then the caller is required to set an |
AcceptLanguages into CIMClient that meets the ISO-639 and IS0-3166 |
AcceptLanguageList into CIMClient that meets the ISO-639 and IS0-3166 |
standards. Note: this is useful for local clients, such as | standards. Note: this is useful for local clients, such as |
the Pegasus CLIs, where ICU would be installed on both the client and | the Pegasus CLIs, where ICU would be installed on both the client and |
server sides. <br> | server sides. <br> |
|
|
<p><br> | <p><br> |
The make messages target will compile these resource bundles. </p> | The make messages target will compile these resource bundles. </p> |
<p>Note: As described above, the resource bundle path in | <p>Note: As described above, the resource bundle path in |
MessageLoaderParms defaults to the server resource bundle. For |
MessageLoaderParms defaults to the server resource bundle. For CLI |
CLI messages, you will need to specify the bundle for your CLI. <br> |
messages, you will need to specify the bundle for your CLI. <br> |
</p> | </p> |
<h3> 5.2 Server Messages</h3> | <h3> 5.2 Server Messages</h3> |
<p><br> | <p><br> |
|
|
<p><b>Server Design Points:</b> <br> | <p><b>Server Design Points:</b> <br> |
</p> | </p> |
<p>The CIMMessage object has been expanded to include an | <p>The CIMMessage object has been expanded to include an |
AcceptLanguages object and a ContentLanguages object. For |
AcceptLanguageList object and a ContentLanguageList object in its |
|
OperationContext member. For |
CIMRequestMessage, these objects contain the Accept-Language and | CIMRequestMessage, these objects contain the Accept-Language and |
Content-Language headers that were built from the client request. | Content-Language headers that were built from the client request. |
For CIMResponseMessage, the ContentLanguages object is used to build |
For CIMResponseMessage, the ContentLanguageList object is used to build the |
the Content-Language header associated with the CIM <i>objects </i>in |
Content-Language header associated with the CIM <i>objects </i>in the |
the response message. The AcceptLanguages object in the |
response message. The AcceptLanguageList object in the |
CIMResponseMessage is ignored. <br> | CIMResponseMessage is ignored. <br> |
</p> | </p> |
<p>The localization of the cimException object in the | <p>The localization of the cimException object in the |
CIMResponseMessage is handled separately from the CIM objects. |
CIMResponseMessage is handled separately from the CIM objects. The |
The message string in the cimException object is assumed to have been |
message string in the cimException object is assumed to have been |
localized by the time it is built into the XML. For this reason, | localized by the time it is built into the XML. For this reason, |
the localization of the exception is the responsibility of the code | the localization of the exception is the responsibility of the code |
throwing the exception. (The goal of the design is to make that | throwing the exception. (The goal of the design is to make that |
easy - see below). The ContentLanguages object in the |
easy - see below). The ContentLanguageList object in the |
CIMResponseMessage has NO relation to this exception. The | CIMResponseMessage has NO relation to this exception. The |
cimException object keeps its own localization information once it is | cimException object keeps its own localization information once it is |
created. <br> | created. <br> |
|
|
<p>To enable exceptions to be localized, the ability was added to set a | <p>To enable exceptions to be localized, the ability was added to set a |
global language for all the code running from a Pegasus Thread | global language for all the code running from a Pegasus Thread |
object. The top level code for a Thread can set a global | object. The top level code for a Thread can set a global |
AcceptLanguages object that can be accessed by all the low-level |
AcceptLanguageList object that can be accessed by all the low-level |
functions that it calls. This will allow an exception thrown by | functions that it calls. This will allow an exception thrown by |
the low-level function to be localized based on this global | the low-level function to be localized based on this global |
AcceptLanguages object. Note: This applies only to Threads |
AcceptLanguageList object. Note: This applies only to Threads |
that are managed by a ThreadPool. <br> | that are managed by a ThreadPool. <br> |
</p> | </p> |
<p>Each service in the request path of the Pegasus server sets the | <p>Each service in the request path of the Pegasus server sets the |
AcceptLanguages into its Thread from the AcceptLanguages in the |
AcceptLanguageList into its Thread from the AcceptLanguageList in the |
CIMRequestMessage object that it dequeues. This sets the global | CIMRequestMessage object that it dequeues. This sets the global |
langauge for all the functions in the same thread that are called below | langauge for all the functions in the same thread that are called below |
handleEnqueue. <i>If you are writing a new service that |
handleEnqueue. <i>If you are writing a new service that processes |
processes requests, or discover a request service that was missed, |
requests, or discover a request service that was missed, please do |
please do this. </i> The CIMOperationRequestDispatcher service is |
this. </i> The CIMOperationRequestDispatcher service is an example. <br> |
an example. <br> |
|
</p> | </p> |
<p><b>How to Throw a Localized Exception from Server code:</b> <br> | <p><b>How to Throw a Localized Exception from Server code:</b> <br> |
</p> | </p> |
<p>With all that background, here is how code running in a Pegasus | <p>With all that background, here is how code running in a Pegasus |
service can throw a localized exception: <br> | service can throw a localized exception: <br> |
This example assumes that the top-level code in the service had set the | This example assumes that the top-level code in the service had set the |
global thread AcceptLanguages beforehand. As described above, |
global thread AcceptLanguageList beforehand. As described above, |
every service in Pegasus should do that. The code here may be | every service in Pegasus should do that. The code here may be |
buried several layers deep in the call chain, but does not need to know | buried several layers deep in the call chain, but does not need to know |
the AcceptLanguage of the current client request. </p> |
the AcceptLanguagList of the current client request. </p> |
<p>// First, construct a MessageLoaderParms <br> | <p>// First, construct a MessageLoaderParms <br> |
// <br> | // <br> |
// Notes: <br> | // Notes: <br> |
|
|
// 3) The MessageLoaderParms will default to use the Pegasus | // 3) The MessageLoaderParms will default to use the Pegasus |
server resource bundle <br> | server resource bundle <br> |
// 4) The MessageLoaderParms will default to use the | // 4) The MessageLoaderParms will default to use the |
AcceptLanguages set into the current Thread. Don't change this! <br> |
AcceptLanguageList set into the current Thread. Don't change this! <br> |
// 5) You might need to set the arguments for the message into | // 5) You might need to set the arguments for the message into |
the MessageLoaderParms <br> | the MessageLoaderParms <br> |
MessageLoaderParms parms("errorMessageID", "default message"); </p> | MessageLoaderParms parms("errorMessageID", "default message"); </p> |
|
|
e.getMessage()); <br> | e.getMessage()); <br> |
} <br> | } <br> |
</p> | </p> |
<p>This type of code would have lost the ContentLanguages saved in "e", |
<p>This type of code would have lost the ContentLanguageList saved in "e", |
so that the Content-Language would not be set in HTTP response to the | so that the Content-Language would not be set in HTTP response to the |
client. <br> | client. <br> |
</p> | </p> |
<p>For Pegasus 2.3, these types of macro calls can stay. The | <p>For Pegasus 2.3, these types of macro calls can stay. The |
TraceableCIMException constructed by the macro will |
TraceableCIMException constructed by the macro will "re-localize". |
"re-localize". That is, the "CIM" part of the message (the part |
That is, the "CIM" part of the message (the part based on the error |
based on the error code) will be localized at throw time, and the |
code) will be localized at throw time, and the ContentLanguageList |
ContentLanguages re-established. A key is to avoid a "language |
re-established. A key is to avoid a "language mismatch" problem |
mismatch" problem between the CIM part of the message and the extra |
between the CIM part of the message and the extra part of the |
part of the message. The design point here is that all internal |
message. The design point here is that all internal exceptions |
exceptions thrown by Pegasus code are localized using the global |
thrown by Pegasus code are localized using the global AcceptLanguageList |
AcceptLanguages of the Thread...see above. <br> |
of the Thread...see above. <br> |
</p> | </p> |
<p>In the future, it will be safer and more maintainable to use of | <p>In the future, it will be safer and more maintainable to use of |
the new "localized" flavors of the macro. For example: <br> | the new "localized" flavors of the macro. For example: <br> |
|
|
e.getMessage( )); <br> | e.getMessage( )); <br> |
} <br> | } <br> |
</p> | </p> |
<p>This guarantees that the ContentLanguages in "e" is copied to the |
<p>This guarantees that the ContentLanguageList in "e" is copied to the |
newly created TraceableCIMException. <br> | newly created TraceableCIMException. <br> |
</p> | </p> |
<p>In the case where the extra message for the CIMException is | <p>In the case where the extra message for the CIMException is |
|
|
<p><br> | <p><br> |
New methods have been added to Logger to take a message ID of a message | New methods have been added to Logger to take a message ID of a message |
to be loaded from the Pegasus server resource bundle. The caller | to be loaded from the Pegasus server resource bundle. The caller |
is only required to pass in the message ID, the old "hardcoded" |
is only required to pass in the message ID, the old "hardcoded" message, |
message, and the args. The Logger will use MessageLoader to load |
and the args. The Logger will use MessageLoader to load the |
the message in the locale of the Pegasus server <i>process</i>, using |
message in the locale of the Pegasus server <i>process</i>, using the |
the hardcoded message as the default string. Please refer to |
hardcoded message as the default string. Please refer to |
pegasus/src/Pegasus/Logger.h. </p> | pegasus/src/Pegasus/Logger.h. </p> |
<p>Note: Messages sent to the "logs", whether the system logs or | <p>Note: Messages sent to the "logs", whether the system logs or |
the Pegasus log file, are converted to UTF-8 before being sent. <br> | the Pegasus log file, are converted to UTF-8 before being sent. <br> |
|
|
-- the user should not be required to tell the CLI what the locale | -- the user should not be required to tell the CLI what the locale |
is. For the CLIs that are CIM clients (cimconfing, | is. For the CLIs that are CIM clients (cimconfing, |
cimprovider) there are two sets of messages to localize -- | cimprovider) there are two sets of messages to localize -- |
messages generated in the CLI process itself, and messages returned |
messages generated in the CLI process itself, and messages returned from |
from the Pegasus server . For CLIs that are directly linked into |
the Pegasus server . For CLIs that are directly linked into |
Pegasus (cimmofl), all the messages are generated in the CLI's process, | Pegasus (cimmofl), all the messages are generated in the CLI's process, |
but the CLI may call Pegasus APIs that are coded to localize based on a | but the CLI may call Pegasus APIs that are coded to localize based on a |
client's requested languages. <br> | client's requested languages. <br> |
|
|
<p>Code in the client side of the client/server CLIs (eg. cimconfig, | <p>Code in the client side of the client/server CLIs (eg. cimconfig, |
cimmof), or in directly linked CLIs (cimmofl), should use the | cimmof), or in directly linked CLIs (cimmofl), should use the |
_useProcessLocale "master switch" described in the Message Loading | _useProcessLocale "master switch" described in the Message Loading |
section. This will cause all messages, including exceptions |
section. This will cause all messages, including exceptions thrown |
thrown by Pegasus APIs, to be loaded in the locale based on the |
by Pegasus APIs, to be loaded in the locale based on the |
environment in which the program is running. This locale can be | environment in which the program is running. This locale can be |
set by the user before running the program. <br> | set by the user before running the program. <br> |
</p> | </p> |
|
|
</p> | </p> |
<p> </p> | <p> </p> |
<hr> | <hr> |
<p><i>Copyright (c) 2003 BMC Software; Hewlett-Packard Development |
<p><i> |
Company, L.P.; IBM Corp.; The Open Group</i> </p> |
Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development |
<p><i>Permission is hereby granted, free of charge, to any person |
Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems. |
obtaining a copy of this software and associated documentation |
Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.; |
files (the "Software"), to deal in the Software without restriction, |
IBM Corp.; EMC Corporation, The Open Group. |
including without limitation the rights to use, copy, modify, merge, |
Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.; |
publish, distribute, sublicense, and/or sell copies of the Software, |
IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group. |
and to permit persons to whom the Software is furnished to do so, |
Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.; |
subject to the following conditions:</i> </p> |
EMC Corporation; VERITAS Software Corporation; The Open Group. |
<p><i>THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE |
Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.; |
INCLUDED IN ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE |
EMC Corporation; Symantec Corporation; The Open Group. |
SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, |
</i> </p> |
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF |
|
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. |
<p><i> |
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY |
Permission is hereby granted, free of charge, to any person obtaining a copy |
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, |
of this software and associated documentation files (the "Software"), to |
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE |
deal in the Software without restriction, including without limitation the |
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.</i> <br> |
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
<br> |
sell copies of the Software, and to permit persons to whom the Software is |
</p> |
furnished to do so, subject to the following conditions: |
|
</i> </p> |
|
|
|
<p><i> |
|
THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN |
|
ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED |
|
"AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT |
|
LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR |
|
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT |
|
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN |
|
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION |
|
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. |
|
</i> <br> |
|
<br> |
|
</p> |
</body> | </body> |
</html> | </html> |