(file) Return to Globalization_HOWTO.htm CVS log (file) (dir) Up to [Pegasus] / pegasus / doc

   1 chuck 1.1 <!doctype html public "-//w3c//dtd html 4.0 transitional//en">
   2           <html>
   3           <head>
   4              <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
   5              <meta name="GENERATOR" content="Mozilla/4.78 [en] (X11; U; Linux 2.4.7-10 i686) [Netscape]">
   6           </head>
   7           <body text="#000000" bgcolor="#FFFFFF" link="#0000EF" vlink="#55188A" alink="#FF0000">
   8           
   9           <center><font size=+4>Globalization HOWTO</font>
  10           <p>Release: Pegasus 2.3
  11           <p>Author: Chuck Carmack (carmack@us.ibm.com)
  12           <p>July 2, 2003</center>
  13           
  14           <p><br>
  15           <br>
  16           <br>
  17           <br>
  18           <br>
  19           <br>
  20           <br>
  21           <br>
  22 chuck 1.1 <br>
  23           <br>
  24           <p>NOTE:&nbsp; THIS IS A WORK-IN-PROGRESS
  25           <br>&nbsp;
  26           <h2>
  27           1.0 Introduction</h2>
  28           
  29           <p><br>As part of the Pegasus 2.3 release, functions were added for globalization
  30           support.&nbsp;&nbsp; Globalization involves two major aspects:&nbsp; internationalization
  31           and localization.
  32           <br>&nbsp;
  33           <p>Internationalization is the process of writing a program that is locale-neutral.&nbsp;
  34           In other words, the program should be able to run in any locale without
  35           change.&nbsp; There are several categories in a locale, including the language
  36           of message strings, date format, time format, etc.&nbsp; For release 2.3,
  37           the Pegasus server is concerned with the language of the message strings
  38           it returns to its clients.
  39           <br>&nbsp;
  40           <p>To support internationalization, a program is designed to do the following:
  41           <br>&nbsp;
  42           <blockquote>
  43 chuck 1.1 <li>
  44           Support character sets that can represent customer data in any language.&nbsp;
  45           Typically, the program supports some variation of Unicode for internal
  46           data.&nbsp; There is usually some conversion between the supported character
  47           sets for external data, and the internal character set.&nbsp; Since Unicode
  48           covers all characters, and usually has converters on the platform, it is
  49           a good choice for the 'normalized' internal character set.&nbsp;&nbsp;&nbsp;
  50           The most 'interoperable' solution for external data is to support UTF-8
  51           (eg. network and file system data).&nbsp; The internal data is usually
  52           UTF-16 (or UCS-2, but that is deprecated).</li>
  53           
  54           <br>&nbsp;
  55           <li>
  56           Extract locale-sensitive resources, such as message strings, from the code
  57           to external resource files.&nbsp; Typically, the resources are loaded based
  58           on the locale requested by the end-user, and returned to the end-user for
  59           display.</li>
  60           </blockquote>
  61           
  62           <p><br>Localization is the process of customizing a software product to
  63           support particular locales.&nbsp; For example, a product that is internationalized
  64 chuck 1.1 might want to only localize for certain countries.&nbsp; This would mean
  65           that the localized resources (eg. message files) would only be translated
  66           and shipped for the countries that the product supports.&nbsp; Since the
  67           code for the product is locale-neutral, it will be easy to drop in new
  68           translations as more countries are supported.
  69           <br>&nbsp;
  70           <p>The Pegasus 2.3 release added support for globalization.&nbsp; At a
  71           high-level, the following additions were made to Pegasus 2.3:
  72           <br>&nbsp;
  73           <ul>
  74           <li>
  75           Support UTF-8 for external data.</li>
  76           
  77           <br>&nbsp;
  78           <ul>
  79           <li>
  80           The CIM-XML documents contained in the HTTP messages</li>
  81           
  82           <li>
  83           Repository files and MOF files&nbsp; (<b>TODO</b> - remove MOF files if
  84           we can't get this into 2.3)</li>
  85 chuck 1.1 </ul>
  86           
  87           <li>
  88           Support UTF-16 for internal data.</li>
  89           
  90           <br>&nbsp;
  91           <li>
  92           Extract the hardcoded messages from the Pegasus code into message files.&nbsp;
  93           An API was added to load messages from the message files.</li>
  94           
  95           <br>&nbsp;
  96           <li>
  97           APIs were added for clients to associate a language with the CIM objects
  98           they are sending to Pegasus.&nbsp; Also, APIs were added for clients to
  99           determine the language of the error message or CIM object that Pegasus
 100           returns.</li>
 101           
 102           <br>&nbsp;
 103           <li>
 104           APIs were added for providers to determine the language of CIM objects
 105           sent by the client.&nbsp; Also, APIs were added for providers to associate
 106 chuck 1.1 a language with the CIM object, or error message, they return to the client.</li>
 107           </ul>
 108           
 109           <p><br>Please refer to PEPs 56 and 58 for details about the globalization
 110           support in Pegasus 2.3.
 111           <br>&nbsp;
 112           <p>This document provides a HOWTO guide to be used by developers to globalize
 113           code that is being added to Pegasus.&nbsp; The audience for this document
 114           are:
 115           <br>&nbsp;
 116           <ul>
 117           <li>
 118           Provider developers - both CMPI and C++</li>
 119           
 120           <li>
 121           Client developers</li>
 122           
 123           <li>
 124           Pegasus developers</li>
 125           </ul>
 126           
 127 chuck 1.1 <p><br>The quickest way to approach this document is to read the General
 128           section, and then the developer section that relates to what you are doing.
 129           <br>&nbsp;
 130           <h2>
 131           2.0 General</h2>
 132           &nbsp;
 133           <h3>
 134           2.1 Unicode Support</h3>
 135           
 136           <p><br>Pegasus 2.3 supports Unicode throughout the processing of requests.&nbsp;
 137           External data to Pegasus is encoded in UTF-8.&nbsp; Internal data is encoded
 138           in UTF-16.
 139           <br>&nbsp;
 140           <p>External data includes the CIM-XML messages passed over the network,
 141           the repository files, and the MOF files.&nbsp; For the CIM-XML messages,
 142           Pegasus follows section 4.8 of the&nbsp; <a href="http://www.dmtf.org/standards/documents/WBEM/DSP200.html">CIM-HTTP
 143           specification</a>&nbsp;&nbsp;&nbsp; Specifically, Pegasus supports the
 144           "utf-8" setting for the charset parameter of the Content-Type header and
 145           the XML encoding attribute.&nbsp; If no charset is specified, the 7-bit
 146           ASCII is assumed.&nbsp; The Pegasus MOF compiler supports UTF-8 encoding
 147           in the MOF files.&nbsp; (<b>TODO</b> - remove this statement if this is
 148 chuck 1.1 not in 2.3)
 149           <br>&nbsp;
 150           <p>The internal support of UTF-16 is encapsulated in the Pegasus String
 151           class.&nbsp; This class has been updated to contain UTF-16 characters.&nbsp;
 152           Specifically, the Char16 objects inside the String contain UTF-16 characters.&nbsp;
 153           Note: a UTF-16 surrogate pair is contained in two consecutive Char16 objects.&nbsp;
 154           To keep backwards compatibilty, the methods on the String class have not
 155           changed.&nbsp; New methods have been added as needed.&nbsp; The following
 156           describes this in more detail:
 157           <ul>
 158           <li>
 159           The Pegasus 2.2 methods that take a char *, or return char *, are unchanged.&nbsp;
 160           Code written to Pegasus 2.2 may have expected to store 8-bit ASCII (ISO-8859-1)
 161           characters into String.&nbsp; These methods will convert the input to UTF-16
 162           from 8-bit ASCII.&nbsp; (This is simple because UTF-16 is a superset of
 163           8-bit ASCII - simply need to prepend '\0' to each char).&nbsp; The Pegasus
 164           2.2 methods that return char data will attempt to convert from the UTF-16
 165           internal representation to 8-bit ASCII.&nbsp; Characters that cannot be
 166           converted will be replaced with a substitution character.</li>
 167           
 168           <br>&nbsp;
 169 chuck 1.1 <li>
 170           All methods that take or return Char16 data are unchanged.&nbsp; The String
 171           class now supports UTF-16 data in Char16, although surrogate pairs will
 172           require two consecutive Char16 objects.&nbsp; The String class does NO
 173           checking for unmatched surrogate pairs.</li>
 174           
 175           <br>&nbsp;
 176           <li>
 177           New methods have been added to take and return UTF-8 data.&nbsp; The String
 178           class will convert between UTF-8 and the UTF-16 internal representation
 179           as needed.&nbsp; These new methods will use char * parameters, but will
 180           be clearly labelled as UTF-8 methods.</li>
 181           
 182           <br>&nbsp;</ul>
 183           PROGRAMMING NOTE:&nbsp; Putting EBCDIC data into the String class is dangerous.&nbsp;
 184           The String class is designed for UTF-16, which is a superset of 8-bit ASCII.&nbsp;
 185           Any String object containing EBCDIC data will not work if it is used by
 186           Pegasus to read or write data from external sources, such as the network
 187           or repository files.&nbsp; In other words, any String containing EBCDIC
 188           data should not leave the code using it.
 189           <br>&nbsp;
 190 chuck 1.1 <br>&nbsp;
 191           <h3>
 192           2.2 Localization Support</h3>
 193           &nbsp;
 194           <h4>
 195           2.2.1 Language Headers</h4>
 196           
 197           <p><br>Pegasus 2.3 supports clients and providers that wish to localize.&nbsp;
 198           There are two areas to be localized:&nbsp; <a href="http://www.dmtf.org/standards/documents/WBEM/DSP201.html#SecERROR">ERROR</a>&nbsp;
 199           elements in the CIM-XML; and&nbsp; <a href="http://www.dmtf.org/standards/documents/WBEM/DSP201.html#SecObjectDefinitionElements">Object
 200           Definition</a>&nbsp; elements in the CIM-XML.&nbsp; Clients can request&nbsp;
 201           the server to return error messages and CIM objects in a set of languages
 202           of their choosing.&nbsp; Clients can also tag a language to the CIM objects
 203           they are sending to the server.&nbsp; Providers and the server can return
 204           error messages and CIM objects that are tagged with one of&nbsp; languages
 205           requested by the client.
 206           <br>&nbsp;
 207           <p>The localization design is based on section 4.8 of the <a href="http://www.dmtf.org/standards/documents/WBEM/DSP200.html">CIM-HTTP
 208           specification</a> , which refers to <a href="http://www.ietf.org/rfc/rfc2616.txt?number=2616">RFC
 209           2616</a>.&nbsp; The method used to tag a language to the CIM-XML is through
 210           the Accept-Language and Content-Language HTTP headers.&nbsp; These headers
 211 chuck 1.1 are basically lists of language tags.&nbsp; An HTTP request can contain
 212           an Accept-Language header, which indicates the list of preferred languages
 213           that the client wants in the response.&nbsp; This list can be prioritized
 214           by using the quality numbers.&nbsp; An HTTP request or response can contain
 215           a Content-Language header, which indicates the language(s) of the content
 216           in the message.&nbsp; In the Pegasus case, this would be the CIM-XML.&nbsp;
 217           Note that the Content-Language header is a list of language tags.&nbsp;
 218           This allows the content of an HTTP message to contain more than one translation.&nbsp;
 219           However, in the Pegasus case, there is only one CIM-XML document in the
 220           HTTP message, and thus one translation.
 221           <br>&nbsp;
 222           <p>CIM clients may use the Accept-Language HTTP header to specify the languages
 223           they wish to be returned in the CIM response message.&nbsp; CIM clients
 224           may also use the Content-Language header to tag the language of any CIM
 225           objects they are sending to the server in the CIM request message.&nbsp;
 226           The server, and providers, should attempt to return error messages and
 227           CIM objects in one of the accept languages requested by the client.&nbsp;
 228           The server and providers should set the Content-Language header in the
 229           CIM response message to indicate which of the requested languages they
 230           are returning.
 231           <br>&nbsp;
 232 chuck 1.1 <p>NOTE:&nbsp; Localization support was not added for the MOF files and
 233           repository in Pegasus 2.3.&nbsp; The #pragma locale, #pragma instancelocale,
 234           and translatable qualifier flavor are not supported in the Pegasus 2.3
 235           MOF compiler.&nbsp; From the client perspective, classes, qualifiers, and
 236           instances stored in the repository as not tagged with a language.&nbsp;
 237           The Accept-Language and Content-Language headers will be ignored for repository
 238           operations.&nbsp; However, since the repository will support UTF-8,&nbsp;
 239           characters for any language may be stored there.
 240           <br>&nbsp;
 241           <p>NOTE:&nbsp; Since the Content-Language header applies to the entire
 242           HTTP message, it applies to the entire CIM-XML document.&nbsp; This includes
 243           all the objects in the document, including enumerated objects, and all
 244           the values in the objects.&nbsp; This is a limitation that will remain
 245           until the CIM standard has been updated to support language tags tied to
 246           individual CIM values.&nbsp; From the client perspective, it is possible
 247           for Pegasus to send a CIM response with NO Content-Language, even if the
 248           client had sent Accept-Language.&nbsp;&nbsp; This can happen if Pegasus
 249           does not know the language of the response.&nbsp; An example is a request
 250           that was sent to a Pegasus 2.2 provider.&nbsp; Another example is an enumerated
 251           response where each provider returned a different language.&nbsp; Please
 252           refer to PEP58 for details on these provider scenarios.
 253 chuck 1.1 <br>&nbsp;
 254           <p>Pegasus 2.3 has added classes for the localization support.&nbsp; There
 255           are new classes called AcceptLanguages and ContentLanguages that encapsulate
 256           the Accept-Language and Content-Language headers, respectively.&nbsp; These
 257           classes are basically containers of AcceptLanguageElement and ContentLanguageElement,
 258           where a language element represents one language tag.&nbsp; The AcceptLanguages
 259           class will keep the AcceptLanguageElement's prioritized based on quality,
 260           according to RFC 2616.
 261           <br>&nbsp;
 262           <p>AcceptLanguages and ContentLanguages are the objects used by code throughout
 263           the request/response processing, from the client to the server to the providers
 264           and back.&nbsp; The server handles the creation of these objects from the
 265           HTTP headers.&nbsp; Code at each point in the process will have access
 266           to these objects.
 267           <br>&nbsp;
 268           <p>Please refer to the following files for details on the new Pegasus classes.
 269           <br>&nbsp;
 270           <ul>
 271           <li>
 272           pegasus/src/Pegasus/Common/AcceptLanguages.h</li>
 273           
 274 chuck 1.1 <li>
 275           pegasus/src/Pegasus/Common/AcceptLanguageElement.h</li>
 276           
 277           <li>
 278           pegasus/src/Pegasus/Common/ContentLanguages.h</li>
 279           
 280           <li>
 281           pegasus/src/Pegasus/Common/ContentLanguageElement.h</li>
 282           
 283           <li>
 284           pegasus/src/Pegasus/Common/LanguageElementContainer.h</li>
 285           
 286           <li>
 287           pegasus/src/Pegasus/Common/LanguageElement.h</li>
 288           </ul>
 289           
 290           <p><br>See the sections below for details on how to write clients and providers
 291           to use these classes.
 292           <br>&nbsp;
 293           <br>&nbsp;
 294           <h4>
 295 chuck 1.1 2.2.2 Message Loading</h4>
 296           
 297           <p><br>One of the goals of globalization for Pegasus 2.3 is the extraction
 298           of hardcoded messages&nbsp; into external message files, and loading messages
 299           from those files.&nbsp; The topics in this section are:&nbsp; how to create
 300           message files, and how to load messages.
 301           <br>&nbsp;
 302           <p>At the time of writing, the message loading function in Pegasus 2.3
 303           used the International Components for Unicode (<a href="http://oss.software.ibm.com/icu">ICU)</a>
 304           libraries.&nbsp; This is expected to be the future direction for Pegasus.
 305           <a href="http://oss.software.ibm.com/icu">ICU
 306           </a>uses
 307           a resource bundle format for their message files.&nbsp;&nbsp; In order
 308           to load the messages, ICU requires that the resource bundles are compiled
 309           into a binary form (.res file) using their genrb tool.
 310           <br>&nbsp;
 311           <p>The documentation for ICU resource bundles is in the <a href="http://oss.software.ibm.com/icu/userguide/ResourceManagement.html">Resource
 312           Management</a>&nbsp; section of the <a href="http://oss.software.ibm.com/icu/userguide/">ICU
 313           User Guide</a> .&nbsp; This section will tell you how to
 314           <br>create, organize, and compile your resource bundles for different languages.&nbsp;
 315           Note:&nbsp; your resource bundles should be organized in a tree structure
 316 chuck 1.1 similiar to the one shown in the Resource Management section, including
 317           the empty bundles in the tree.
 318           <br>&nbsp;
 319           <p>NOTE:&nbsp; Pegasus 2.3 only supports simple string resources in the
 320           ICU resource bundles.&nbsp; String resources may only be loaded by key.&nbsp;
 321           Tables, arrays, and other complex resource types, are not supported.
 322           <br>&nbsp;
 323           <p>Code that needs to load a message in Pegasus does not call ICU directly.&nbsp;
 324           Two message loading classes were added for Pegasus 2.3:&nbsp; MessageLoader
 325           and MessageLoaderParms.&nbsp; These classes are abstractions designed to
 326           hide of the actual loader used.&nbsp;&nbsp; The MessageLoader is used to
 327           load a message using a list of preferrred languages.&nbsp; The parameters
 328           to MessageLoader are encapsulated in a MessageLoaderParms object.
 329           <br>&nbsp;
 330           <p>The MessageLoaderParms object contains the parameters to load the message.&nbsp;
 331           There are many parameters, but many can be allowed to default.&nbsp; Here
 332           is a description of the parameters:
 333           <br>&nbsp;
 334           <p>NOTE:&nbsp; WORK-IN- PROGRESS
 335           <br>&nbsp;
 336           <br>&nbsp;
 337 chuck 1.1 <table BORDER COLS=3 WIDTH="100%" NOSAVE >
 338           <tr>
 339           <td>String msg_id;&nbsp;</td>
 340           
 341           <td>Input.&nbsp;
 342           <br>Required.</td>
 343           
 344           <td>Message ID&nbsp; of the message to load from the resource bundle.&nbsp;
 345           This is the key that ICU will use to load the message.</td>
 346           </tr>
 347           
 348           <tr>
 349           <td>String default_msg;</td>
 350           
 351           <td>Input.&nbsp;
 352           <br>Required</td>
 353           
 354           <td>Message to return if the no message can be loaded for msg_id from a
 355           resource bundle.&nbsp; Note:&nbsp; The args parameters below are substituted
 356           into this string.&nbsp;
 357           <br>Note:&nbsp; For the args into this&nbsp; string, use the Pegasus '$'
 358 chuck 1.1 form, as described in pegasus/src/Pegasus/Common/Formatter.h.&nbsp; Don't
 359           use the ICU substitution format for the default message string.</td>
 360           </tr>
 361           
 362           <tr>
 363           <td>String msg_src_path;&nbsp;</td>
 364           
 365           <td>Input.&nbsp;
 366           <br>Optional
 367           <br>Default: $PEGASUS_HOME/msg/pegasus/pegasusServer</td>
 368           
 369           <td>Path to the root resource bundle file which contains the msg_id.&nbsp;
 370           Do not include the language or file extension as part of the path.
 371           <br>Note: relative paths start at $PEGASUS_HOME/msg.&nbsp;</td>
 372           </tr>
 373           
 374           <tr>
 375           <td>AcceptLanguages acceptlanguages;</td>
 376           
 377           <td>Input.&nbsp;
 378           <br>Optional
 379 chuck 1.1 <br>Default: AcceptLanguages::EMPTY</td>
 380           
 381           <td>Contains the list of preferred languages, in priority order.&nbsp;
 382           This is combined with msg_src_path to determine which resource bundles
 383           to search for for the msg_id.&nbsp;&nbsp; If not EMPTY, overrides useThreadLocale
 384           and useProcessLocale.</td>
 385           </tr>
 386           
 387           <tr>
 388           <td>ContentLanguages contentlanguages;</td>
 389           
 390           <td>Output</td>
 391           
 392           <td>Contains the language that MessageLoader found for the msg_id.&nbsp;</td>
 393           </tr>
 394           
 395           <tr>
 396           <td>Boolean useProcessLocale;</td>
 397           
 398           <td>Input
 399           <br>Optional
 400 chuck 1.1 <br>Default = false</td>
 401           
 402           <td>If true, MessageLoader will use the default locale of the process.&nbsp;
 403           If true, overrides useThreadLocale.</td>
 404           </tr>
 405           
 406           <tr>
 407           <td>Boolean useThreadLocale;</td>
 408           
 409           <td>Input
 410           <br>Optional
 411           <br>Default = <font color="#FF0000">true</font></td>
 412           
 413           <td>If true, MessageLoader will use the locale of the caller's thread.&nbsp;</td>
 414           </tr>
 415           
 416           <tr>
 417           <td>Boolean useICUfallback</td>
 418           
 419           <td>Input
 420           <br>Optional
 421 chuck 1.1 <br>Default = false</td>
 422           
 423           <td>If true, use ICU's fallback mechnism to search more general resource
 424           bundles if the msg_id cannot be found.&nbsp; Note: the recommended setting
 425           is false if you are using an AcceptLanguages from a CIM client.&nbsp; The
 426           Accept-Languages HTTP header from the client contains the fallback specifications.</td>
 427           </tr>
 428           
 429           <tr>
 430           <td>Formatter::Arg arg0;
 431           <br>&nbsp;Formatter::Arg arg1;
 432           <br>&nbsp;Formatter::Arg arg2;
 433           <br>&nbsp;Formatter::Arg arg3;
 434           <br>&nbsp;Formatter::Arg arg4;
 435           <br>&nbsp;Formatter::Arg arg5;
 436           <br>&nbsp;Formatter::Arg arg6;
 437           <br>&nbsp;Formatter::Arg arg7;
 438           <br>&nbsp;Formatter::Arg arg8;
 439           <br>&nbsp;Formatter::Arg arg9;</td>
 440           
 441           <td>Input
 442 chuck 1.1 <br>Optional
 443           <br>Default: Formatter::Arg( ) // empty arg</td>
 444           
 445           <td>These are the substitution variables, using the Pegasus Formatter::Arg
 446           class.</td>
 447           </tr>
 448           </table>
 449           
 450           <p>Please refer to the following files for details on the new Pegasus classes.
 451           <br>&nbsp;
 452           <ul>
 453           <li>
 454           pegasus/src/Pegasus/Common/MessageLoader.h</li>
 455           </ul>
 456           
 457           <h4>
 458           2.2.3 Message Loading Example</h4>
 459           &nbsp;
 460           <p>&nbsp;
 461           <br>&nbsp;
 462           <br>&nbsp;
 463 chuck 1.1 <br>&nbsp;
 464           <br>&nbsp;
 465           <br>&nbsp;
 466           <br>&nbsp;
 467           <br>&nbsp;
 468           <br>&nbsp;
 469           <br>&nbsp;
 470           <br>&nbsp;
 471           <p>The following example shows how a message may be loaded using the classes
 472           described above.&nbsp; Note: this a generic example.&nbsp; Each of the
 473           developer sections below have 'real-life' examples that are better suited
 474           to each type of code.
 475           <p>// Build an AcceptLanguages with some language elements
 476           <br>AcceptLanguages acceptLangs;
 477           <br>acceptLangs.add(AcceptLanguageElement("fr", 0.5));
 478           <br>acceptLangs.add(AcceptLanguageElement("de", 0.8));
 479           <br>acceptLangs.add(AcceptLanguageElement("es", 0.4));
 480           <p>// Construct a MessageLoaderParms
 481           <br>MessageLoaderParms parms("msgID", "default message");
 482           <br>parms. msg_src_path = "/my_msg_dir/my_bundle";
 483           <br>parms.acceptlanguages = acceptLangs;
 484 chuck 1.1 <p>// Note: If you have args, set them into MessageLoaderParms
 485           <p>// Load the localized String
 486           <br>String localizedMsg = MessageLoader::getMessage(parms);
 487           <br>&nbsp;
 488           <br>&nbsp;
 489           <h4>
 490           2.2.4 Message Writing Guidelines</h4>
 491           
 492           <p><br>Here are some basic rules for writing messages:
 493           <br>&nbsp;
 494           <ul>
 495           <li>
 496           If you want to claim that you are globalized, no hardcoded messages!</li>
 497           
 498           <li>
 499           Avoid combining messages in the code from other messages.&nbsp; When you
 500           do this you are assuming that you know the grammar for every language.</li>
 501           
 502           <li>
 503           String substitutions into messages are generally untranslated, ie. not
 504           loaded from the resource bundle.&nbsp;&nbsp; Example: a file name.</li>
 505 chuck 1.1 
 506           <li>
 507           Avoid jargon, humour, and cultural idioms.&nbsp; Use full sentences.&nbsp;
 508           Have your messages reviewed by your globalization team.&nbsp; Your messages
 509           need to make sense to the translators, and ultimately the customer.</li>
 510           
 511           <li>
 512           <b>TODO </b>- find a good message writing guide to link to</li>
 513           </ul>
 514           
 515           <h2>
 516           3.0 Provider Developers</h2>
 517           &nbsp;
 518           <h3>
 519           3.1 Design Issues</h3>
 520           
 521           <p><br>Providers that wish to globalize should consider the following in
 522           their design:
 523           <br>&nbsp;
 524           <ul>
 525           <li>
 526 chuck 1.1 Are there localized string properties that need to be supported?&nbsp;
 527           If so, then the client will use Accept-Language to request specific languages
 528           for these properties.&nbsp; If the properties are read-only, use MessageLoader
 529           to load the localized strings for the properties.</li>
 530           
 531           <li>
 532           If you have a localized read/write string property, then the client will
 533           use Content-Language to set the property with an associated language.&nbsp;
 534           The client will expect to be able to retrieve the property in that same
 535           language later (using Accept-Language).</li>
 536           
 537           <li>
 538           Note: only the string property types in CIM are candidates for localization.&nbsp;
 539           The other types, including datetime, are locale-neutral.</li>
 540           
 541           <li>
 542           Are there error messages that need to returned to the client in different
 543           languages?&nbsp; The client will use Accept-Language to request specific
 544           languages for the error messages.</li>
 545           
 546           <li>
 547 chuck 1.1 What resource bundle translations, if any, will be shipped with the provider?</li>
 548           
 549           <li>
 550           Do any codepage conversions need to be done between the UTF-16 characters
 551           in the String objects and the codepage of data stored on the system?&nbsp;
 552           This is a concern for EBCDIC platforms.&nbsp; All EBCDIC data needs to
 553           be converted to at least 7-bit ASCII before it is passed into the String
 554           object.</li>
 555           </ul>
 556           
 557           <p><br>To help providers handle the situations described above, Pegasus
 558           2.3 will pass the Accept-Language received from the client to the provider.&nbsp;
 559           The provider should load strings from its resource bundle based on the
 560           client's Accept-Language.&nbsp; The client's Accept-Language is passed
 561           to the provider in two ways:
 562           <br>&nbsp;
 563           <ul>
 564           <li>
 565           Pegasus will set the Accept-Language from the client into the thread in
 566           which the provider is running.&nbsp; By using the useThreadLocale setting
 567           in MessageLoaderParms, providers can easily load strings using the client's
 568 chuck 1.1 requested Accept-Language.&nbsp; The provider does not need to know what
 569           the Accept-Language is.&nbsp; This is the recommended method to load messages
 570           based on the client's request.</li>
 571           
 572           <br>&nbsp;
 573           <li>
 574           The OperationContext will contain an AcceptLanguages object that has the
 575           Accept-Language requested by the client.&nbsp; The provider can use this
 576           AcceptLanguages object to load strings with MessageLoader.</li>
 577           </ul>
 578           
 579           <p><br>The OperationContext will also contain a ContentLanguages object
 580           that is set from the Content-Language in the client request.&nbsp; This
 581           is the language of the CIM objects being passed to the provider on that
 582           request.&nbsp; A localized provider should store the content language along
 583           with the data from the CIM objects.&nbsp; This will allow the client to
 584           use Accept-Language later to retreive the data in that language.
 585           <br>&nbsp;
 586           <p>The provider should indicate the language of CIM objects it is returning
 587           by calling setLanguage( ) on the ResponseHandler.&nbsp; This will be used
 588           to set the Content-Language in the CIM response message sent back to the
 589 chuck 1.1 client.&nbsp; If setLanguage( ) is not called, then no Content-Language
 590           will be returned to the client.&nbsp; setLanguage( ) should only be called
 591           once per response.
 592           <br>&nbsp;
 593           <h3>
 594           3.2 Sample Code</h3>
 595           
 596           <p><br>The following sample code shows a localized getInstance( ) where
 597           the instance returned is localized based on the Accept-Language of the
 598           client request.&nbsp; Note that this example also throws a localized exception.
 599           <br>&nbsp;
 600           <p>void LocalizedProvider::getInstance(
 601           <br>&nbsp;&nbsp;&nbsp; const OperationContext &amp; context,
 602           <br>&nbsp;&nbsp;&nbsp; const CIMObjectPath &amp; instanceReference,
 603           <br>&nbsp;&nbsp;&nbsp; const Boolean includeQualifiers,
 604           <br>&nbsp;&nbsp;&nbsp; const Boolean includeClassOrigin,
 605           <br>&nbsp;&nbsp;&nbsp; const CIMPropertyList &amp; propertyList,
 606           <br>&nbsp;&nbsp;&nbsp; InstanceResponseHandler &amp; handler)
 607           <br>{
 608           <br>&nbsp;&nbsp;&nbsp;&nbsp; // convert a potential fully qualified reference
 609           into a local reference
 610 chuck 1.1 <br>&nbsp;&nbsp;&nbsp;&nbsp; // (class name and keys only).
 611           <br>&nbsp;&nbsp;&nbsp;&nbsp; CIMObjectPath localReference = CIMObjectPath(
 612           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String(),
 613           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String(),
 614           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; instanceReference.getClassName(),
 615           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; instanceReference.getKeyBindings());
 616           <p>&nbsp;&nbsp;&nbsp;&nbsp; // begin processing the request
 617           <br>&nbsp;&nbsp;&nbsp;&nbsp; handler.processing();
 618           <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // Find the instance to be returned.
 619           <br>&nbsp;&nbsp;&nbsp;&nbsp; Uint32 i;
 620           <br>&nbsp;&nbsp;&nbsp;&nbsp; Uint32 n = _instances.size();
 621           <br>&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0;&nbsp; i &lt; n;&nbsp; i++)
 622           <br>&nbsp;&nbsp;&nbsp;&nbsp; {
 623           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if(localReference
 624           == _instanceNames[i])
 625           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
 626           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 627           // We found the instance to return
 628           <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 629           // Build the parameters for loading the localized string property.
 630           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 631 chuck 1.1 // We are going to let the message loader parameters default to use the
 632           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 633           // AcceptLanguages that Pegasus set into our thread.
 634           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 635           // (this equals the AcceptLanguages requested by the client)
 636           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 637           // Note: This parms object could be constructed once and
 638           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 639           // reused.
 640           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 641           MessageLoaderParms parms("myMsgID", "myDefaultString");
 642           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 643           parms.msg_src_path = "/myprovider/msg/myResourceBundle";
 644           <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 645           // Load the string for the localized property from the resource bundle
 646           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 647           String localizedString = MessageLoader::getMessage(parms);
 648           <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 649           // Remove the old property from the instance to be returned
 650           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 651           Uint32 index = instances[i].findProperty("myProperty");
 652 chuck 1.1 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 653           if (index != PEG_NOT_FOUND)
 654           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 655           {
 656           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 657           _instances[i].removeProperty(index);
 658           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 659           }
 660           <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 661           // Add the localized string property to the instance
 662           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 663           instances[i].addProperty(CIMProperty("myProperty", localizedString));
 664           <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 665           // The MessageLoader set the contentlanguages member
 666           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 667           // of parms to the language that it found for the message.
 668           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 669           ContentLanguages rtnLangs = parms.contentlanguages;
 670           <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 671           // We need to tag the instance we are returning with the
 672           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 673 chuck 1.1 // the content language.
 674           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 675           handler.setLanguages(rtnLangs);
 676           <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 677           // deliver requested instance
 678           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 679           handler.deliver(_instances[i]);
 680           <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 681           break;
 682           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 683           }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp; end if
 684           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 685           // end for
 686           <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // throw an exception if
 687           the instance wasn't found
 688           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (i == n)
 689           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {
 690           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 691           // Build the parameters for loading the localized error message.
 692           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 693           // We are going to let the message loader parameters default to use the
 694 chuck 1.1 <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 695           // AcceptLanguages that Pegasus set into our thread.
 696           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 697           // (this equals the AcceptLanguages requested by the client)
 698           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 699           // Note: This parms object could be constructed once and
 700           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 701           // reused.
 702           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 703           MessageLoaderParms errParms("myErrorMsgID", "myErrorDefaultString");
 704           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 705           errParms.msg_src_path = "/myprovider/msg/myResourceBundle";
 706           <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 707           // Note: the exception calls MessageLoader::getMessage( )
 708           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 709           // Note: no need to call handler.setLanguages( ) in this case
 710           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 711           throw CIMObjectNotFoundException(errParms);
 712           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }
 713           <br>&nbsp;
 714           <p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // complete processing the
 715 chuck 1.1 request
 716           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; handler.complete();
 717           <br>}
 718           <br>&nbsp;
 719           <p>NOTE: A sample provider has been written that fully demonstates the
 720           design issues described above.&nbsp; This provider is located at:
 721           <br>&nbsp;
 722           <ul>
 723           <li>
 724           pegasus/src/Providers/sample/LocalizedProvider/</li>
 725           </ul>
 726           
 727           <p><br>This sample provider also demonstrates how some of the special issues
 728           can be handled.&nbsp; The special issues are caused by having a read/only
 729           localized property and a read/write localized property.&nbsp; What happens
 730           if the client sets the read/write property with a Content-Language that
 731           is not one of the supported languages for the read/only property?&nbsp;
 732           This provider allows the client to set any language into the read/write
 733           property, and get that property back in the same language.&nbsp; This becomes
 734           an issue when the client does a getInstance( ) later, because the Content-Language
 735           on the returned instance applies to all the properties.&nbsp; A related
 736 chuck 1.1 issue is what to return for Content-Language when the client does enumerateInstances,
 737           but the instances have different languages.&nbsp; Recall that Content-Language
 738           applies to the entire response (a limitation in the CIM specification).
 739           <br>&nbsp;
 740           <p>NOTE:&nbsp; Indication Providers have other special considerations for
 741           language support.&nbsp; Please refer to&nbsp; PEP58.
 742           <br>&nbsp;
 743           <p>NOTE:&nbsp; The CMPI interface has been updated for language support.&nbsp;
 744           Please refer to the CMPI documentation for details.
 745           <br>&nbsp;
 746           <p>NOTE: SPECIAL ISSUES FOR OS/400 PROVIDERS:
 747           <ul>
 748           <li>
 749           Convert between UTF-16 in the String objects and EBCDIC system data as
 750           needed.&nbsp; The converters in Pegasus/Common/OS400ConvertChar.h may be
 751           used to convert between EBCDIC CCSID 37 and ASCII CCSID 819 (a subset of
 752           UTF-16).</li>
 753           
 754           <li>
 755           The Pegasus program, and all bound service programs,&nbsp; will run in
 756           a UTF-8 locale even though the job CCSID is 37.&nbsp; The C-runtime library
 757 chuck 1.1 (printf, fopen, isalpha, strcmp, etc) will expect UTF-8, or at least 7-bit
 758           ASCII, characters.</li>
 759           
 760           <li>
 761           Consideration should be given to the codepage for the compiled string literals.&nbsp;
 762           Use #pragma convert as needed.&nbsp; But, remember that the C-runtime will
 763           expect UTF-8.</li>
 764           
 765           <li>
 766           For more details, refer to "Unicode support" in chapter 3 of the <u>ILE
 767           C/C++ for iSeries Run-Time Functions, Version 5</u> publication for V5R3
 768           (SC41-5607-02).&nbsp; The Pegasus string literals will be compiled with
 769           the UTF-8 compile switch described in this section.&nbsp; OS/400 provider
 770           developers should strongly consider using the same compile switch for their
 771           string literals.&nbsp; This would allow the literals to match the UTF-8
 772           encoding expected by the C-runtime.</li>
 773           </ul>
 774           
 775           <h2>
 776           4. 0 Client Developers</h2>
 777           
 778 chuck 1.1 <p><br>Methods have been added to CIMClient to set the Accept-Language
 779           and Content-Language on the request, and retrieve Content-Language on the
 780           response.
 781           <br>&nbsp;
 782           <p>Please refer to
 783           <br>&nbsp;
 784           <ul>
 785           <li>
 786           pegasus/src/Pegasus/Client/CIMClient.h</li>
 787           
 788           <br>&nbsp;</ul>
 789           for the new methods on CIMClient.
 790           <br>&nbsp;
 791           <p>Here is a code fragment that uses the new methods on CIMClient
 792           <p>&nbsp;&nbsp;&nbsp; //
 793           <br>&nbsp;&nbsp;&nbsp; // Get a localized instance in French
 794           <br>&nbsp;&nbsp;&nbsp; //
 795           <p>&nbsp;&nbsp; // Language priority is martian, pig-latin, and french.&nbsp;
 796           We should
 797           <br>&nbsp;&nbsp; // get french back, even though its the lowest priority
 798           <br>&nbsp; AcceptLanguages acceptLangs;
 799 chuck 1.1 <br>&nbsp; acceptLangs.add(AcceptLanguageElement("x-martian"));
 800           <br>&nbsp; acceptLangs.add(AcceptLanguageElement("fr", 0.1));
 801           <br>&nbsp; acceptLangs.add(AcceptLanguageElement("x-pig-latin", 0.4));
 802           <p>&nbsp;&nbsp;&nbsp; // Set the requested languages into the CIMClient
 803           <br>&nbsp; client.setRequestAcceptLanguages(acceptLangs);
 804           <p>&nbsp;&nbsp; // Get the instance
 805           <br>&nbsp; CIMInstance instance = client.getInstance(
 806           <br>&nbsp;&nbsp;&nbsp; NAMESPACE,
 807           <br>&nbsp;&nbsp;&nbsp; cimNInstances[0].buildPath(sampleClass),
 808           <br>&nbsp;&nbsp;&nbsp; localOnly,
 809           <br>&nbsp;&nbsp;&nbsp; includeQualifiers,
 810           <br>&nbsp;&nbsp;&nbsp; includeClassOrigin);
 811           <p>&nbsp; // Get the string property that should be french
 812           <br>&nbsp; String returnedString;
 813           <br>&nbsp; instance.getProperty (
 814           <br>&nbsp;&nbsp;&nbsp; instance.findProperty("myProp")).
 815           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 816           getValue().
 817           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 818           get(returnedString);
 819           <p>&nbsp; // Check that we got back french
 820 chuck 1.1 <br>&nbsp; ContentLanguages CL_FR("fr");
 821           <br>&nbsp; String expectedFRString = "oui";
 822           <br>&nbsp; PEGASUS_ASSERT(CL_FR == client.getResponseContentLanguages());
 823           <br>&nbsp; PEGASUS_ASSERT(expectedFRString == returnedString);
 824           <p>&nbsp;&nbsp;&nbsp; //
 825           <br>&nbsp;&nbsp;&nbsp; // Create an instance in French
 826           <br>&nbsp;&nbsp;&nbsp; //
 827           <p>&nbsp;&nbsp; String oui = "Oui";
 828           <br>&nbsp;&nbsp; CIMInstance frInstance(CLASSNAME);
 829           <br>&nbsp;&nbsp; frInstance.addProperty(CIMProperty(
 830           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 831           CIMName("myProp"),
 832           <br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
 833           oui));
 834           <p>&nbsp;&nbsp; CIMObjectPath frInstanceName = frInstance.buildPath(sampleClass);
 835           <p>&nbsp;&nbsp; client.setRequestContentLanguages(CL_FR);
 836           <p>&nbsp;&nbsp; client.createInstance(NAMESPACE, frInstance);
 837           <br>&nbsp;
 838           <br>&nbsp;
 839           <br>&nbsp;
 840           <p>Also, refer to
 841 chuck 1.1 <ul>
 842           <li>
 843           pegasus/src/Clients/g11ntest/</li>
 844           </ul>
 845           for more examples of a client that uses Accept-Language and Content-Language.
 846           <br>&nbsp;
 847           <p>NOTE:&nbsp; Consideration should be given for converting the UTF-16
 848           characters in the String objects passed over the CIMClient interface to
 849           a platform codepage.&nbsp; This is especially needed for EBCDIC platforms.&nbsp;
 850           See the Provider developer section for details of the EBCDIC considerations.
 851           <br>&nbsp;
 852           <p><b>TODO</b> - some info on how CIMClient defaults the Accept-Languages.
 853           <br>&nbsp;
 854           <h2>
 855           5. 0 Pegasus Developers</h2>
 856           
 857           <p><br>The design for Pegasus releases beyond 2.3 is to avoid using hardcoded
 858           messages.&nbsp; All new messages should be loaded from a Pegasus resource
 859           bundle.&nbsp; This section describes the process to follow if you are creating
 860           a new message.&nbsp; The process depends on where you are in the code.
 861           <br>&nbsp;
 862 chuck 1.1 <br>&nbsp;
 863           <h3>
 864           <b>5.1 Pegasus Resource Bundles</b></h3>
 865           
 866           <p><br>Place any new Pegasus messages into one of the following resource
 867           bundles:
 868           <br>&nbsp;
 869           <ul>
 870           <li>
 871           pegasus/src/Pegasus/msg/Server/pegasusServer.txt&nbsp; for server messages</li>
 872           
 873           <li>
 874           pegasus/src/Clients/&lt;cli_name>/msg/&lt;cli_name>.txt for CLI messages</li>
 875           </ul>
 876           Note:&nbsp; As described above, the resource bundle path in MessageLoaderParms
 877           defaults to the server resource bundle.&nbsp; For CLI messages, you will
 878           need to specify the bundle for your CLI.
 879           <br>&nbsp;
 880           <h3>
 881           5.2 Server Messages</h3>
 882           
 883 chuck 1.1 <p><br>For messages returned from one of the services in the Pegasus server
 884           (eg. CIMOperationRequestDispatcher, or ProviderManagerService), the goal
 885           is to make it easy for any code in the call chain to throw an exception
 886           with a localized error string.&nbsp; The code throwing the exception will
 887           not need to know the Accept-Language that the client requested.&nbsp; To
 888           understand how this works, some design points need to described:
 889           <br>&nbsp;
 890           <p><b>Server Design Points:</b>
 891           <br>&nbsp;
 892           <p>The CIMMessage object has been expanded to include an AcceptLanguages
 893           object and a ContentLanguages object.&nbsp; For CIMRequestMessage, these
 894           objects contain the Accept-Language and Content-Language headers that were
 895           built from the client request.&nbsp; For CIMResponseMessage, the ContentLanguages
 896           object is used to build the Content-Language header associated with the
 897           CIM <i>objects </i>in the response message.&nbsp; The AcceptLanguages object
 898           in the CIMResponseMessage is ignored.
 899           <br>&nbsp;
 900           <p>The localization of the cimException object in the CIMResponseMessage
 901           is handled separately from the CIM objects.&nbsp; The message string in
 902           the cimException object is assumed to have been localized by the time it
 903           is built into the XML.&nbsp; For this reason, the localization of the exception
 904 chuck 1.1 is the responsibility of the code throwing the exception.&nbsp; (The goal
 905           of the design is to make that easy - see below).&nbsp; The ContentLanguages
 906           object in the CIMResponseMessage has NO relation to this exception.&nbsp;
 907           The cimException object keeps its own localization information once it
 908           is created.
 909           <br>&nbsp;
 910           <p>To enable exceptions to be localized, the ability was added to set a
 911           global language for all the code running from a Pegasus Thread object.&nbsp;
 912           The top level code for a Thread can set a global AcceptLanguages object
 913           that can accessed by all the low-level functions that it calls.&nbsp; This
 914           will allow an exception thrown by low-level code to be localized based
 915           on this global AcceptLanguages object.&nbsp; Note:&nbsp; This applies only
 916           to Threads that are managed by a ThreadPool.
 917           <br>&nbsp;
 918           <p>Each service in the request path of the Pegasus server sets the AcceptLanguages
 919           into its Thread from the AcceptLanguages in the CIMRequestMessage object
 920           that it dequeues.&nbsp; This sets the global langauge for all the functions
 921           in the same thread that are called below handleEnqueue.&nbsp; <i>If you
 922           are writing a new service that processes requests, or discover a request
 923           service that was missed, please do this.&nbsp;</i> The CIMOperationRequestDispatcher
 924           service is an example.
 925 chuck 1.1 <br>&nbsp;
 926           <p><b>How to Throw a Localized Exception from Server code:</b>
 927           <br>&nbsp;
 928           <p>With all that background, here is how code running in a Pegasus service
 929           can throw a localized exception:
 930           <br>This example assumes that the top-level code in the service had set
 931           the global thread language beforehand.&nbsp; As described above, every
 932           service in Pegasus should do that.
 933           <p>// First, construct a MessageLoaderParms
 934           <br>//
 935           <br>// Notes:
 936           <br>//&nbsp; 1) The errorMessageID must be in the Pegasus server resource
 937           bundle.
 938           <br>//&nbsp; 2) The default message is the old "hardcoded" message.
 939           <br>//&nbsp; 3) The MessageLoaderParms will default to use the Pegasus
 940           server resource bundle
 941           <br>//&nbsp; 4) The MessageLoaderParms will default to use the locale of
 942           the current thread.&nbsp; Don't change this!
 943           <br>//&nbsp; 5) You might need to set the arguments for the message into
 944           the MessageLoaderParms
 945           <br>MessageLoaderParms parms("errorMessageID", "default message");
 946 chuck 1.1 <p>// Second, throw the Exception
 947           <br>// Note: this applies to all the derived classes from Exception, including
 948           the CIMException's
 949           <br>throw new Exception(parms);
 950           <br>&nbsp;
 951           <p>NOTE:&nbsp; If you are throwing an Exception with un-localized data,
 952           use the constructor that takes a String.&nbsp; An example of this would
 953           be an Exception where you are passing in a file name.&nbsp; Most of the
 954           "non-CIM" exceptions defined in Exception.h and InternalException.h take
 955           un-localized data.
 956           <br>&nbsp;
 957           <p><b>How to Load a Localized Message</b>
 958           <p>For code that may <i>not </i>be running in a Thread with the global
 959           language set, but has access to the AcceptLanguages object from the CIMMessage,
 960           <br>the code is simple:
 961           <p>// Construct a MessageLoaderParms
 962           <br>//
 963           <br>// Notes:
 964           <br>//&nbsp; 1) The errorMessageID must be in the Pegasus server resource
 965           bundle.
 966           <br>//&nbsp; 2) The default message is the old "hardcoded" message.
 967 chuck 1.1 <br>//&nbsp; 3) The MessageLoaderParms will default to use the Pegasus
 968           server resource bundle
 969           <br>//&nbsp; 4) The MessageLoaderParms will default to use the locale of
 970           the current thread.&nbsp; You will change this below.
 971           <br>//&nbsp; 5) You might need to set the arguments for the message into
 972           the MessageLoaderParms
 973           <br>MessageLoaderParms parms("errorMessageID", "default message");
 974           <p>// Tell the MessageLoaderParms which languages to search for.
 975           <br>// MessageLoaderParms will not use the thread locale in this case.
 976           <br>parms.acceptlanguages = &lt;pass in the AcceptLanguages object>
 977           <p>// Load the localized String
 978           <br>String localizedMsg = MessageLoader::getMessage(parms);
 979           <br>&nbsp;
 980           <h3>
 981           5.2 Logger Messages</h3>
 982           
 983           <p><br>New methods have been added to Logger to take a message ID of a
 984           message to be loaded from the Pegasus server resource bundle.&nbsp; The
 985           caller is only required to pass in the message ID, and the old "hardcoded"
 986           message, and the args.&nbsp; The Logger will use MessageLoader to load
 987           the message in the locale of the Pegasus server <i>process</i>, using the
 988 chuck 1.1 hardcoded message as the default string.&nbsp; Please refer to pegasus/src/Pegasus/Logger.h
 989           <br>&nbsp;
 990           <h3>
 991           5.3 CLI Messages</h3>
 992           
 993           <p><br>Code in the client side of the client/server CLIs (eg. cimconfig,
 994           cimmof), or in directly linked CLIs (cimmofl), should use the useProcessLocale
 995           setting in MessageLoaderParms.&nbsp; This will cause the messages to be
 996           loaded in the locale based on the environment in which the program is running.&nbsp;
 997           This locale can be set by the user before running the program.
 998           <p><b>TODO - </b>describe how CIMClient will default the Accept-Language
 999           from the process locale.
1000           <br>&nbsp;
1001           <br>&nbsp;
1002           <p>
1003           <hr>
1004           <p><i>Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company,
1005           L.P.; IBM Corp.; The Open Group</i>
1006           <p><i>Permission is hereby granted, free of charge, to any person obtaining
1007           a copy&nbsp; of this software and associated documentation files (the "Software"),
1008           to deal in the Software without restriction, including without limitation
1009 chuck 1.1 the rights to use, copy, modify, merge, publish, distribute, sublicense,
1010           and/or sell copies of the Software, and to permit persons to whom the Software
1011           is furnished to do so, subject to the following conditions:</i>
1012           <p><i>THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED
1013           IN ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS
1014           PROVIDED&nbsp; "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
1015           INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
1016           FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
1017           OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
1018           WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
1019           OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
1020           SOFTWARE.</i>
1021           <br>&nbsp;
1022           <br>&nbsp;
1023           </body>
1024           </html>

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2