BUG#: 5840
[tpot/pegasus/.git] / src / Pegasus / Common / MessageLoader.h
1 //%2006////////////////////////////////////////////////////////////////////////
2 //
3 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
6 // IBM Corp.; EMC Corporation, The Open Group.
7 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
11 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
13 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
20 // 
21 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
34 #ifndef Pegasus_MessageLoader_h
35 #define Pegasus_MessageLoader_h
36
37 #include <cstdlib>
38 #include <cctype>
39 #include <Pegasus/Common/Linkage.h>
40 #include <Pegasus/Common/Config.h>
41 #include <Pegasus/Common/String.h>
42 #include <Pegasus/Common/Formatter.h>
43 #include <Pegasus/Common/AcceptLanguageList.h>
44 #include <Pegasus/Common/ContentLanguageList.h>
45
46 //ICU specific
47 #ifdef PEGASUS_HAS_ICU
48 # include <unicode/uloc.h>
49 # include <unicode/ures.h>
50 # include <unicode/umsg.h>
51 # include <unicode/ucnv.h>
52 # include <unicode/fmtable.h>
53 # include <unicode/msgfmt.h>
54 #endif
55
56 #ifdef PEGASUS_HAS_ICU
57 # define NO_ICU_MAGIC (UResourceBundle*)0xDEADBEEF
58 #else
59 # define NO_ICU_MAGIC (void*)0xDEADBEEF
60 #endif
61
62 PEGASUS_NAMESPACE_BEGIN
63
64 /**
65     MessageLoaderParms class is basically a stuct class containing public
66     variables that control the way MessageLoader behaves. MessageLoader uses
67     the fields in this class to decide where and how to load messages from
68     the message resources.
69  */
70 class PEGASUS_COMMON_LINKAGE MessageLoaderParms
71 {
72 public:
73
74     /**
75         String msg_id: unique message identifier for a particular
76         message in a message resource
77      */
78     String msg_id;
79
80     /**
81         String default_msg: the default message to use if a message
82         cannot be loaded from a message resource
83      */
84     String default_msg;
85
86     /**
87         String msg_src_path: this path tells MessageLoader where to
88         find message resources.
89         It can be empty, fully qualified or relative to $PEGASUS_HOME
90      */
91     String msg_src_path;
92
93     /**
94         AcceptLanguageList acceptlanguages: This contains the languages
95         that are acceptable by the caller of MessageLoader::getMessage()
96         or openMessageFile(). That is, MessageLoader will do its best to
97         return a message in a language that was specified in this container.
98         This container is naturally ordered using the quality values
99         attached to the languages and MessageLoader iterates through this
100         container in its natural ordering.  This container is used by
101         MessageLoader to load messages if it is not empty.
102      */
103     AcceptLanguageList acceptlanguages;
104
105     /**
106         ContentLanguageList contentlanguages: This is set by
107         MessageLoader::getMessage() and after a message has been loaded
108         from either a message resource or the default message, or by
109         MessageLoader::openMessageFile() after it has identified and
110         opened a message resource. After the call to
111         MessageLoader::getMessage() or MessageLoader::openMessageFile(),
112         the caller can check the MessageLoaderParms.contentlanguages
113         object to see what MessageLoader set it to. In all cases where a
114         message is returned from MessageLoader::getMessage() or will be
115         returned from MessageLoader::getMessage2(), this field will be
116         set to match the language that the message was (or will be)
117         found in.
118      */
119     ContentLanguageList contentlanguages;
120
121     /**
122         Boolean useProcessLocale: Default is false, if true, MessageLoader
123         uses the system default language to loads messages from.
124      */
125     Boolean useProcessLocale;
126
127     /**
128         Boolean useThreadLocale: Default is true, this tells
129         MessageLoader to use the AcceptLanguageList container
130         from the current Pegasus thread.
131      */
132     Boolean useThreadLocale;
133
134     /**
135         Boolean useICUfallback: Default is false.  Only relevant if
136         PEGASUS_HAS_ICU is defined.  MessageLoader::getMessage() default
137         behaviour is to extract messages for the langauge exactly
138         matching an available message resource.  If this is set to true,
139         the MessageLoader is free to extract a message from a less
140         specific message resource according to its search algorithm.
141      */
142 #ifdef PEGASUS_HAS_ICU
143     Boolean useICUfallback;
144 #endif
145
146     /**
147         const Formatter::Arg&0-9: These are assigned the various
148         substitutions necessary to properly format the message being
149         extracted.  MessageLoader substitutes these in the correct
150         places in the message being returned from
151         MessageLoader::getMessage()
152      */
153     Formatter::Arg arg0;
154     Formatter::Arg arg1;
155     Formatter::Arg arg2;
156     Formatter::Arg arg3;
157     Formatter::Arg arg4;
158     Formatter::Arg arg5;
159     Formatter::Arg arg6;
160     Formatter::Arg arg7;
161     Formatter::Arg arg8;
162     Formatter::Arg arg9;
163
164     /** Constructor */
165     MessageLoaderParms();
166
167     /** Constructor */
168     MessageLoaderParms(
169         const String& id,
170         const String& msg,
171         const Formatter::Arg& arg0,
172         const Formatter::Arg& arg1,
173         const Formatter::Arg& arg2,
174         const Formatter::Arg& arg3,
175         const Formatter::Arg& arg4,
176         const Formatter::Arg& arg5 = Formatter::DEFAULT_ARG,
177         const Formatter::Arg& arg6 = Formatter::DEFAULT_ARG,
178         const Formatter::Arg& arg7 = Formatter::DEFAULT_ARG,
179         const Formatter::Arg& arg8 = Formatter::DEFAULT_ARG,
180         const Formatter::Arg& arg9 = Formatter::DEFAULT_ARG);
181
182     /** Constructor */
183     MessageLoaderParms(
184         const String& id,
185         const String& msg);
186
187     /** Constructor */
188     MessageLoaderParms(
189         const String& id,
190         const String& msg,
191         const Formatter::Arg& arg0);
192
193     /** Constructor */
194     MessageLoaderParms(
195         const String& id,
196         const String& msg,
197         const Formatter::Arg& arg0,
198         const Formatter::Arg& arg1);
199
200     /** Constructor */
201     MessageLoaderParms(
202         const String& id,
203         const String& msg,
204         const Formatter::Arg& arg0,
205         const Formatter::Arg& arg1,
206         const Formatter::Arg& arg2);
207
208     /** Constructor */
209     MessageLoaderParms(
210         const String& id,
211         const String& msg,
212         const Formatter::Arg& arg0,
213         const Formatter::Arg& arg1,
214         const Formatter::Arg& arg2,
215         const Formatter::Arg& arg3);
216
217     MessageLoaderParms(
218         const char* id,
219         const char* msg);
220
221     MessageLoaderParms(
222         const char* id,
223         const char* msg,
224         const String& arg0);
225
226     MessageLoaderParms(
227         const char* id,
228         const char* msg,
229         const String& arg0,
230         const String& arg1);
231
232     /** Converts to string. */
233     String toString();
234
235     ~MessageLoaderParms();
236
237 private:
238 #ifdef PEGASUS_HAS_ICU
239     UResourceBundle* _resbundl;
240 #else
241     void* _resbundl;
242 #endif
243
244     void _init();
245
246     friend class MessageLoader;
247 };
248
249
250 /**
251     MessageLoader is a static class resposible for looking up messages in
252     message resources.
253     For specific behaviour details of this class see the Globalization HOWTO.
254  */
255 class PEGASUS_COMMON_LINKAGE MessageLoader
256 {
257 public:
258
259     /**
260         Retrieves a message from a message resource
261         @param parms MessageLoaderParms - controls the behaviour of how a
262         message is retrieved
263         @return String - the formatted message
264      */
265     static String getMessage(MessageLoaderParms& parms);
266
267     /**
268         Opens a message resource bundle.
269         If this method fails for some reason, it will set parms.resbundl
270         to NO_ICU_MAGIC, and a subsequent call to getMessage2() will
271         result in the default message being formatted.
272         ATTN: Do we want *real* error codes for this?
273         @param parms MessageLoaderParms - controls the behaviour of how a
274             message is retrieved, this parameter should be used *ONLY* on
275             subsequent calls to getMessage2() and closeMessageFile().
276      */
277     static void openMessageFile(MessageLoaderParms& parms);
278
279     /**
280         Closes a message resource bundle.
281         @param parms MessageLoaderParms - identifies a previously opened
282             resource bundle returned from openMessageFile().
283      */
284     static void closeMessageFile(MessageLoaderParms& parms);
285
286     /**
287         Retrieves a message from a message resource previously opened by
288         openMessageFile()
289         @param parms MessageLoaderParms - controls the behaviour of how a
290             message is retrieved, and is the same MessageLoaderParms
291             parameter that was passed to openMessageFile().
292         @return String - the formatted message
293      */
294     static String getMessage2(MessageLoaderParms& parms);
295
296     static void setPegasusMsgHome(String home);
297
298     static void setPegasusMsgHomeRelative(const String& argv0);
299
300     static Boolean _useProcessLocale;
301
302     static Boolean _useDefaultMsg;
303
304     static AcceptLanguageList _acceptlanguages;
305
306 private:
307
308     static String formatDefaultMessage(MessageLoaderParms& parms);
309
310     static String getQualifiedMsgPath(String path);
311
312     static void initPegasusMsgHome(const String& startDir);
313
314     static void checkDefaultMsgLoading();
315
316     static String pegasus_MSG_HOME;
317
318 #ifdef PEGASUS_HAS_ICU
319     static void openICUMessageFile(MessageLoaderParms& parms);
320
321     static String extractICUMessage(
322         UResourceBundle* resbundl,
323         MessageLoaderParms& parms);
324
325     static String formatICUMessage(
326         UResourceBundle* resbundl,
327         const UChar* msg,
328         int msg_len,
329         MessageLoaderParms& parms);
330
331     static String uChar2String(UChar* uchar_str);
332
333     static String uChar2String(UChar* uchar_str, int len);
334
335     static void xferFormattable(Formatter::Arg& arg, Formattable& formattable);
336 #endif
337
338 };
339
340 PEGASUS_NAMESPACE_END
341
342 #endif