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