(file) Return to MessageLoader.cpp CVS log (file) (dir) Up to [Pegasus] / pegasus / src / Pegasus / Common

  1 karl  1.23 //%2005////////////////////////////////////////////////////////////////////////
  2 humberto 1.4  //
  3 karl     1.18 // 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 karl     1.9  // IBM Corp.; EMC Corporation, The Open Group.
  7 karl     1.18 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
  8               // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
  9 karl     1.23 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
 10               // EMC Corporation; VERITAS Software Corporation; The Open Group.
 11 humberto 1.4  //
 12               // Permission is hereby granted, free of charge, to any person obtaining a copy
 13               // of this software and associated documentation files (the "Software"), to
 14               // deal in the Software without restriction, including without limitation the
 15               // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 16               // sell copies of the Software, and to permit persons to whom the Software is
 17               // furnished to do so, subject to the following conditions:
 18 chip     1.27 //
 19 humberto 1.4  // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
 20               // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
 21               // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
 22               // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
 23               // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
 24               // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
 25               // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 26               // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 27               //
 28               //==============================================================================
 29 chip     1.27 //
 30 humberto 1.4  // Author: Humberto Rivero (hurivero@us.ibm.com)
 31               //
 32 joyce.j  1.34 // Modified By: Josephine Eskaline Joyce, IBM (jojustin@in.ibm.com) for Bug#3032
 33 chip     1.27 //
 34 humberto 1.4  //%/////////////////////////////////////////////////////////////////////////////
 35               
 36               #include <Pegasus/Common/MessageLoader.h>
 37               #include <Pegasus/Common/Thread.h>
 38               #include <Pegasus/Common/Tracer.h>
 39 david    1.15 #include <Pegasus/Common/Constants.h>
 40 yi.zhou  1.30 #include <Pegasus/Common/CommonUTF.h>
 41 joyce.j  1.34 #include <Pegasus/Common/FileSystem.h>
 42 humberto 1.6  #include <iostream>
 43               #ifdef PEGASUS_OS_OS400
 44               #include "OS400ConvertChar.h"
 45               #endif
 46 chip     1.27 PEGASUS_NAMESPACE_BEGIN
 47 humberto 1.6  PEGASUS_USING_STD;
 48 humberto 1.4  
 49               static const int ID_INVALID = -1;
 50               static const String server_resbundl_name = "pegasus/pegasusServer";
 51 humberto 1.7  String MessageLoader::pegasus_MSG_HOME = String();
 52 humberto 1.4  Boolean MessageLoader::_useProcessLocale = false;
 53               Boolean MessageLoader::_useDefaultMsg = false;
 54               AcceptLanguages MessageLoader::_acceptlanguages = AcceptLanguages();
 55               
 56               	String MessageLoader::getMessage(MessageLoaderParms &parms){
 57               		PEG_METHOD_ENTER(TRC_L10N, "MessageLoader::getMessage");
 58 humberto 1.8  		try{
 59 yi.zhou  1.30 		        parms.contentlanguages.clear();
 60               
 61               #if defined (PEGASUS_HAS_MESSAGES) && defined (PEGASUS_HAS_ICU)
 62               		        if (InitializeICU::initICUSuccessful())
 63                                       {
 64                                           String msg = loadICUMessage(parms);
 65               
 66                                           if (msg.size() > 0)
 67                                           {
 68               		 	        PEG_METHOD_EXIT();
 69               			        return (msg);
 70                                           }
 71                                       }
 72               
 73               #endif
 74               			// NOTE: the default message is returned if:
 75               			// Message loading is DIABLED or
 76               			// A non-ICU message loading function is called that has
 77               			// non-ICU process locale discovery code and non-ICU 
 78               			// message loading or
 79               			// InitializeICU::initICUSuccessful() is failed or
 80 yi.zhou  1.30 			// Did not get a message from ICU
 81 chip     1.27 
 82 kumpf    1.25 			PEG_METHOD_EXIT();
 83 humberto 1.4  			return formatDefaultMessage(parms);
 84 chip     1.27 
 85 kumpf    1.10 		}catch(Exception&){
 86 kumpf    1.25 			PEG_METHOD_EXIT();
 87 chip     1.27 			return String("AN INTERNAL ERROR OCCURED IN MESSAGELOADER: ").append(parms.default_msg);
 88 carson.hovey 1.24 		}
 89 humberto     1.4  	}
 90 chip         1.27 
 91 chuck        1.22 #ifdef PEGASUS_HAS_ICU
 92 chip         1.27 
 93 humberto     1.4  	String MessageLoader::loadICUMessage(MessageLoaderParms &parms){
 94 chip         1.27 
 95 humberto     1.4  		PEG_METHOD_ENTER(TRC_L10N, "MessageLoader::loadICUMessage");
 96                   		String msg;
 97                   		UResourceBundle* resbundl;
 98                   		UErrorCode status = U_ZERO_ERROR;
 99 chip         1.27 		//String resbundl_path_ICU;
100 humberto     1.4  		CString resbundl_path_ICU;
101 chip         1.27 
102 humberto     1.4  		// the static AcceptLangauges takes precedence over what parms.acceptlangauges has
103                   		AcceptLanguages acceptlanguages;
104                   		acceptlanguages = (_acceptlanguages.size() > 0) ? _acceptlanguages : parms.acceptlanguages;
105 chip         1.27 
106 humberto     1.4  		// get the correct path to the resource bundles
107 humberto     1.6  		resbundl_path_ICU = getQualifiedMsgPath(parms.msg_src_path).getCString();
108 chuck        1.13 
109                   		// if someone has set the global behaviour to use default messages
110                   		// Note: this must be after the call to getQualifiedMsgPath
111 kumpf        1.25 		if (_useDefaultMsg)
112                   		{
113                   			PEG_METHOD_EXIT();
114 chip         1.27 			return formatDefaultMessage(parms);
115 kumpf        1.25 		}
116 chuck        1.13 
117 humberto     1.6  		//cout << "USING PACKAGE PATH: " << endl;
118                   		//cout << resbundl_path_ICU << endl;
119 humberto     1.17 		PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4, "Using resource bundle path:");
120                   		PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4, resbundl_path_ICU);
121 chuck        1.22 #ifdef PEGASUS_OS_OS400
122 humberto     1.6  		const char *atoe = resbundl_path_ICU;
123                   		AtoE((char*)atoe);
124 chuck        1.22 #endif
125 chip         1.27 
126                   
127                   
128 humberto     1.4  		if(_useProcessLocale || (acceptlanguages.size() == 0 && parms.useProcessLocale)){ // use the system default resource bundle
129 chip         1.27 
130                   			resbundl = ures_open((const char*)resbundl_path_ICU, uloc_getDefault() , &status);
131                   
132 humberto     1.4  			if(U_SUCCESS(status)) {
133                   				//cout << "PROCESS_LOCALE: opened resource bundle" << endl;
134 humberto     1.17 				UErrorCode _status = U_ZERO_ERROR;
135                   				//cout << "PROCESS_LOCALE = " << ures_getLocale(resbundl, &_status) << endl;
136                   				PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4, "Using process locale:");
137                   				PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4, ures_getLocale(resbundl, &_status));
138 humberto     1.4  				if(status == U_USING_FALLBACK_WARNING || status == U_USING_DEFAULT_WARNING){
139 chip         1.27 					//cout << "PROCESS_LOCALE: using fallback or default" << endl;
140 humberto     1.17 					PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4, "Using process locale fallback or default");
141 humberto     1.4  				}
142                       			msg = extractICUMessage(resbundl,parms);
143 humberto     1.6  
144                   			String cl_str(ures_getLocale(resbundl,&status));
145 chuck        1.22 #ifdef PEGASUS_OS_OS400
146 humberto     1.6  			   CString cstr = cl_str.getCString();
147                   		           const char *etoa = cstr;
148                   			   EtoA((char*)etoa);
149                   			   cl_str = etoa;
150 chuck        1.22 #endif
151 humberto     1.6      			parms.contentlanguages.append(ContentLanguageElement(cl_str));
152 chip         1.27     			ures_close(resbundl);
153 humberto     1.4  			} else {
154                   				//cout << "PROCESS_LOCALE: could not open resouce, formatting default message" << endl;
155 humberto     1.17 				PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4, "Using process locale.  Could not open resource, formatting default message.");
156 humberto     1.4      			msg = formatDefaultMessage(parms);
157                   			}
158 kumpf        1.25 			PEG_METHOD_EXIT();
159 humberto     1.4  			return msg;
160                   		} else if (acceptlanguages.size() == 0 && parms.useThreadLocale){ // get AcceptLanguages from the current Thread
161                   			AcceptLanguages *al = Thread::getLanguages();
162 chip         1.27 			if(al != NULL){
163 humberto     1.4  				acceptlanguages = *al;
164 chip         1.27 				//cout << "THREAD_LOCALE: got acceptlanguages from thread" << endl;
165 humberto     1.17 				PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4, "Using thread locale: got AcceptLanguages from thread.");
166 chip         1.27 			}else {
167 humberto     1.4  				//cout << "THREAD_LOCALE: thread returned NULL for acceptlanguages" << endl;
168 humberto     1.17 				PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4, "Using thread locale: thread returned NULL for AcceptLanguages.");
169 chip         1.27 			 }
170 humberto     1.4  		}
171 chip         1.27 
172 humberto     1.4  		const int size_locale_ICU = 50;
173                   		char locale_ICU[size_locale_ICU];
174                   		AcceptLanguageElement language_element = AcceptLanguageElement::EMPTY;
175 chip         1.27 
176 humberto     1.4  		// iterate through AcceptLanguages, use the first resource bundle match
177                   		acceptlanguages.itrStart();
178                   		//cout << "LOOPING THROUGH ACCEPTLANGUAGES..." << endl;
179 humberto     1.17 		PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4, "Looping through AcceptLanguages...");
180 humberto     1.4  		while((language_element = acceptlanguages.itrNext()) != AcceptLanguageElement::EMPTY_REF){
181 chuck        1.22 #ifdef PEGASUS_OS_OS400
182 humberto     1.6  		        CString cstr = language_element.getTag().getCString();
183                   			const char *atoe = cstr;
184                   			AtoE((char*)atoe);
185                   			String tag(atoe);
186                   		        uloc_getName((const char*)tag.getCString(), locale_ICU, size_locale_ICU, &status);
187 chuck        1.22 #else
188 humberto     1.6  			uloc_getName((const char*)(language_element.getTag()).getCString(), locale_ICU, size_locale_ICU, &status);
189 chuck        1.22 #endif
190 chip         1.27 			//cout << "locale_ICU = " << locale_ICU << endl;
191 humberto     1.4  			// TODO: check to see if we have previously cached the resource bundle
192 chip         1.27 
193 humberto     1.4  			resbundl = ures_open((const char*)resbundl_path_ICU, locale_ICU, &status);
194 chip         1.27 
195 humberto     1.4  			if(U_SUCCESS(status)) {
196                   				//cout << "ACCEPTLANGUAGES LOOP: opened resource bundle with " << language_element.getTag() << endl;
197 humberto     1.17 				PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4, "ACCEPTLANGUAGES LOOP: opened resource bundle with:");
198                   				PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4, language_element.getTag());
199 humberto     1.4  				if(status == U_USING_FALLBACK_WARNING || status == U_USING_DEFAULT_WARNING){
200                   					//we want to use the ICU fallback behaviour in the following cases ONLY
201                   					//cout << "ACCEPTLANGUAGES LOOP: ICU warns using FALLBACK or DEFAULT" << endl;
202 humberto     1.17 					PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4,"ACCEPTLANGUAGES LOOP: ICU warns using FALLBACK or DEFAULT");
203 humberto     1.12 					if((acceptlanguages.size() == 1) && (!parms.useICUfallback) && (status == U_USING_DEFAULT_WARNING)){
204                   						// in this case we want to return messages from the root bundle
205                   						status = U_ZERO_ERROR;
206                   						//cout << "ML::acceptlang.size =1 && !parms.useICUfallback && U_USING_DEFAULT_WARNING" << endl;
207 humberto     1.17 						PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4,"acceptlang.size =1 && !parms.useICUfallback && U_USING_DEFAULT_WARNING, using root bundle.");
208 chuck        1.22 
209                                     // Reopen the bundle in the root locale
210                                     ures_close(resbundl);
211                                     resbundl = ures_open((const char*)resbundl_path_ICU, "", &status);
212                                     if(U_SUCCESS(status)) {
213                                       msg = extractICUMessage(resbundl,parms);
214                                       ures_close(resbundl);
215                                       break;
216                                     }
217 humberto     1.12 					}
218                   					else if(acceptlanguages.size() == 1 || parms.useICUfallback){
219 humberto     1.4  						//cout << "ACCEPTLANGUAGES LOOP: acceptlanguages.size == 1 or useICUfallback true, using ICU fallback behaviour..." << endl;
220 humberto     1.17 						PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4,"ACCEPTLANGUAGES LOOP: acceptlanguages.size == 1 or useICUfallback true, using ICU fallback behaviour...");
221 humberto     1.6  						msg = extractICUMessage(resbundl,parms);
222                   
223                   						String cl_str(ures_getLocale(resbundl,&status));
224 chuck        1.22 #ifdef PEGASUS_OS_OS400
225                                     CString cstr = cl_str.getCString();
226                                     const char *etoa = cstr;
227                                     EtoA((char*)etoa);
228                                     cl_str = etoa;
229                   #endif
230 humberto     1.6  						parms.contentlanguages.append(ContentLanguageElement(cl_str));
231 humberto     1.4  						ures_close(resbundl);
232                   						break;
233 chip         1.27 					}
234 humberto     1.4  				}
235 chip         1.27 				else{  // we found an exact resource bundle match, extract, and set ContentLanguage
236 humberto     1.4  					//cout << "ACCEPTLANGUAGES LOOP: found an EXACT resource bundle MATCH" << endl;
237 humberto     1.17 					PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4,"ACCEPTLANGUAGES LOOP: found an EXACT resource bundle MATCH:");
238                   					PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4,language_element.getTag());
239 humberto     1.4  					msg = extractICUMessage(resbundl,parms);
240 chip         1.27 					parms.contentlanguages.append(ContentLanguageElement(language_element.getTag()));
241                       				ures_close(resbundl);
242 humberto     1.4      				break;
243 chip         1.27 				}
244 humberto     1.4  			} else { // possible errors, ex: message path incorrect
245                       			// for now do nothing, let the while loop continue
246 chip         1.27     			//cout << "ACCEPTLANGUAGES LOOP: could NOT open a resource for: " << language_element.getTag() << endl;
247 humberto     1.4  			}
248                   			status = U_ZERO_ERROR;  // reset status
249                   		}
250 chuck        1.22 
251 humberto     1.2  		// now if we DIDNT get a message, we want to enable ICU fallback for the highest priority language
252 humberto     1.4  		if(msg.size() == 0 && acceptlanguages.size() > 0){
253 humberto     1.3  			//cout << "USING ICU FALLBACK" << endl;
254 humberto     1.17 			PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4,"No message was loaded, using ICU fallback behaviour.");
255 humberto     1.2  			language_element = acceptlanguages.getLanguageElement(0);
256 humberto     1.6  
257 chuck        1.22 #ifdef PEGASUS_OS_OS400
258 humberto     1.6  		        CString cstr = language_element.getTag().getCString();
259                   			const char *atoe = cstr;
260                   			AtoE((char*)atoe);
261                   			String tag(atoe);
262 chuck        1.22          uloc_getName((const char*)tag.getCString(), locale_ICU, size_locale_ICU, &status);
263                   #else
264 humberto     1.6  			uloc_getName((const char*)(language_element.getTag()).getCString(), locale_ICU, size_locale_ICU, &status);
265 chuck        1.22 #endif
266 humberto     1.3  			//cout << "locale_ICU in fallback = " << locale_ICU << endl;
267 humberto     1.6  			status = U_ZERO_ERROR;
268 humberto     1.4  			resbundl = ures_open((const char*)resbundl_path_ICU, locale_ICU, &status);
269 humberto     1.6  			String cl_str_;
270                   			if(U_SUCCESS(status)) {
271                   				if(status == U_USING_DEFAULT_WARNING){
272                   					//cout << "PRIORITY ICU FALLBACK: using default resource bundle with " << language_element.getTag() << endl;
273 humberto     1.17 					PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4,"PRIORITY ICU FALLBACK: using default resource bundle with ");
274                   					PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4, language_element.getTag());
275 humberto     1.6  					status = U_ZERO_ERROR;
276 chuck        1.22 
277                                  // Reopen the bundle in the root locale
278                                  ures_close(resbundl);
279 humberto     1.6  					resbundl = ures_open((const char*)resbundl_path_ICU, "", &status);
280                   					if(U_SUCCESS(status)) {
281                   						msg = extractICUMessage(resbundl,parms);
282                   			    		cl_str_ = ures_getLocale(resbundl,&status);
283                   					}
284                   				}else{
285                   			    	msg = extractICUMessage(resbundl,parms);
286                   			    	cl_str_ = ures_getLocale(resbundl,&status);
287                   			    }
288 chuck        1.22 #ifdef PEGASUS_OS_OS400
289 humberto     1.6  			    CString cstr_ = cl_str_.getCString();
290                   			    const char *etoa = cstr_;
291                   			    EtoA((char*)etoa);
292                   			    cl_str_ = etoa;
293 chuck        1.22 #endif
294 humberto     1.6  			    if(cl_str_ != "root")
295 chuck        1.22                parms.contentlanguages.append(ContentLanguageElement(cl_str_));
296 humberto     1.6  			    ures_close(resbundl);
297 humberto     1.5  			}
298 humberto     1.2  		}
299 chuck        1.22 
300 humberto     1.6  		if(msg.size() == 0){ 			// else if no message, load message from root bundle explicitly
301 humberto     1.4  			//cout << "EXHAUSTED ACCEPTLANGUAGES: using root bundle to extract message" << endl;
302 humberto     1.17 			PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4,"EXHAUSTED ACCEPTLANGUAGES: using root bundle to extract message");
303 chip         1.27 			status = U_ZERO_ERROR;
304 humberto     1.4  			resbundl = ures_open((const char*)resbundl_path_ICU, "", &status);
305                   			if(U_SUCCESS(status)){
306                   				//cout << "EXHAUSTED ACCEPTLANGUAGES: opened root resource bundle" << endl;
307 humberto     1.17 				PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4,"EXHAUSTED ACCEPTLANGUAGES: opened root resource bundle");
308 humberto     1.4  				msg = extractICUMessage(resbundl,parms);
309                   				//parms.contentlanguages.append(ContentLanguageElement(String(ures_getLocale(resbundl,&status))));
310 chuck        1.22             ures_close(resbundl);
311 chip         1.27 			}else {
312                   				//cout << "EXHAUSTED ACCEPTLANGUAGES: could NOT open root resource bundle" << endl;
313 humberto     1.17 				PEG_TRACE_STRING(TRC_L10N, Tracer::LEVEL4,"EXHAUSTED ACCEPTLANGUAGES: could NOT open root resource bundle");
314 humberto     1.4  			}
315                   
316                   		}
317                   		PEG_METHOD_EXIT();
318 chip         1.27 		return msg;
319 humberto     1.4  	}
320 chip         1.27 
321 humberto     1.4  	String MessageLoader::extractICUMessage(UResourceBundle * resbundl, MessageLoaderParms &parms){
322 chip         1.27 		UErrorCode status = U_ZERO_ERROR;
323 humberto     1.4  		int32_t msgLen = 0;
324 humberto     1.6  
325 chuck        1.22 #ifdef PEGASUS_OS_OS400
326 humberto     1.6  		CString cstr = parms.msg_id.getCString();
327                   		const char *atoe = cstr;
328                   		AtoE((char*)atoe);
329                   		const UChar *msg = ures_getStringByKey(resbundl, (const char*)atoe, &msgLen, &status);
330 chuck        1.22 #else
331 humberto     1.4  		const UChar *msg = ures_getStringByKey(resbundl, (const char*)parms.msg_id.getCString(), &msgLen, &status);
332 chuck        1.22 #endif
333 chip         1.27    		if(U_FAILURE(status)) {
334 humberto     1.4  	  		//cout << "could not extract ICU Message" << endl;
335                   	  		return String::EMPTY;
336 chip         1.27 		}
337 humberto     1.4  
338                   		return formatICUMessage(resbundl, msg, msgLen, parms);
339                   	}
340 chip         1.27 
341 humberto     1.4  	String MessageLoader::uChar2String(UChar * uchar_str){
342                   		return String((const Char16 *)uchar_str);
343 chip         1.27 	}
344                   
345 humberto     1.4  	String MessageLoader::uChar2String(UChar * uchar_str, int len){
346                   		return String((const Char16 *)uchar_str, len);
347                   	}
348 chip         1.27 
349 humberto     1.4  	String MessageLoader::formatICUMessage(UResourceBundle * resbundl, const UChar * msg, int msg_len, MessageLoaderParms &parms){
350 chip         1.27 
351 humberto     1.4  		// format the message
352                   		UnicodeString msg_pattern(msg, msg_len);
353                   		UnicodeString msg_formatted;
354                   		UErrorCode status = U_ZERO_ERROR;
355                   		const int arg_count = 10;
356 vijay.eli    1.31 		const char *locale;
357 humberto     1.4  		if(resbundl == NULL)
358                   			 locale = ULOC_US;
359                   		else
360 vijay.eli    1.32 			 locale = ures_getLocale(resbundl, &status);
361 chip         1.27 
362 humberto     1.4  		//cout << "FORMAT ICU MESSAGE: using locale = " << locale << endl;
363 chip         1.27 
364                   		char lang[4];
365 humberto     1.4  		char cc[4];
366                   		char var[arg_count];
367                   		uloc_getLanguage(locale, lang, 4, &status);
368                   		uloc_getCountry(locale, cc, 4, &status);
369                   		uloc_getVariant(locale, var, 10, &status);
370                   		Locale localeID(lang,cc,var);
371 chip         1.27 
372 humberto     1.4  		status = U_ZERO_ERROR;
373                   		MessageFormat formatter(msg_pattern, localeID, status);
374 chuck        1.21 
375 humberto     1.4  		Formattable args[arg_count];
376 chuck        1.21 
377                         if (parms.arg0._type != Formatter::Arg::VOIDT)
378                           xferFormattable(parms.arg0, args[0]);
379                         if (parms.arg1._type != Formatter::Arg::VOIDT)
380                           xferFormattable(parms.arg1, args[1]);
381                         if (parms.arg2._type != Formatter::Arg::VOIDT)
382                           xferFormattable(parms.arg2, args[2]);
383                         if (parms.arg3._type != Formatter::Arg::VOIDT)
384                           xferFormattable(parms.arg3, args[3]);
385                         if (parms.arg4._type != Formatter::Arg::VOIDT)
386                           xferFormattable(parms.arg4, args[4]);
387                         if (parms.arg5._type != Formatter::Arg::VOIDT)
388                           xferFormattable(parms.arg5, args[5]);
389                         if (parms.arg6._type != Formatter::Arg::VOIDT)
390                           xferFormattable(parms.arg6, args[6]);
391                         if (parms.arg7._type != Formatter::Arg::VOIDT)
392                           xferFormattable(parms.arg7, args[7]);
393                         if (parms.arg8._type != Formatter::Arg::VOIDT)
394                           xferFormattable(parms.arg8, args[8]);
395                         if (parms.arg9._type != Formatter::Arg::VOIDT)
396                           xferFormattable(parms.arg9, args[9]);
397 chuck        1.21 
398 humberto     1.4  		Formattable args_obj(args,arg_count);
399                   		status = U_ZERO_ERROR;
400                   		msg_formatted = formatter.format(args_obj, msg_formatted, status);
401 chip         1.27 
402 humberto     1.4  		return uChar2String(const_cast<UChar *>(msg_formatted.getBuffer()), msg_formatted.length());
403 chip         1.27 	}
404                   
405 chuck        1.21 	void MessageLoader::xferFormattable(Formatter::Arg& arg, Formattable &formattable)
406                      {
407                   			//cout << "arg" << " = " << arg.toString() << endl;
408                   			switch (arg._type)
409 humberto     1.4      		{
410 chuck        1.33 				case Formatter::Arg::INTEGER:
411                                       formattable = (int32_t)arg._integer;
412                                       break;
413                   				case Formatter::Arg::UINTEGER:
414                                       // Note: the ICU Formattable class doesn't support
415                                       // unsigned 32.  Cast to signed 64.
416                                       formattable = (int64_t)arg._uinteger;
417                                       break;
418                   				case Formatter::Arg::BOOLEAN:
419                                       // Note: the ICU formattable class doesn't support
420                                       // boolean.  Turn it into a string.
421                                       if (!arg._boolean)
422                                           formattable = Formattable("false");
423                                       else
424                                           formattable = Formattable("true");
425                                       break;
426                   				case Formatter::Arg::REAL:
427                                       formattable = (double)arg._real;
428                                       break;
429                   				case Formatter::Arg::LINTEGER:
430                                       // Note: this uses a Formattable constructor that is
431 chuck        1.33                     // labelled ICU 2.8 draft.  Assumes that Pegasus uses
432                                       // at least ICU 2.8.
433                                       formattable = (int64_t)arg._lInteger;
434                                       break;
435                   				case Formatter::Arg::ULINTEGER:
436                                       // Note: the ICU Formattable class doesn't support
437                                       // unsigned 64.  If the number is too big for signed 64
438                                       // then turn it into a string.  This string will  
439                                       // not be formatted for the locale, but at least the number
440                                       // will appear in the message.
441                                       if (arg._lUInteger >  PEGASUS_UINT64_LITERAL(0x7FFFFFFFFFFFFFFF))
442                                       {
443                                           char buffer[32];  // Should need 21 chars max
444                                           sprintf(buffer, "%" PEGASUS_64BIT_CONVERSION_WIDTH "u", arg._lUInteger);
445                                           formattable = Formattable(buffer);
446                                       }
447                                       else
448                                       {
449                                           formattable = (int64_t)arg._lUInteger;
450                                       }
451                                       break;
452 chuck        1.33 				case Formatter::Arg::STRING:
453                                       formattable = Formattable((UChar*)arg._string.getChar16Data());
454                                       break;
455 chip         1.27 	    		case Formatter::Arg::VOIDT:
456                               default:
457 chuck        1.21               formattable = "";
458                                 break;
459 chip         1.27 			}
460 chuck        1.21    }
461                   
462                   
463 chuck        1.22 #endif
464 chip         1.27 
465 humberto     1.4  	String MessageLoader::formatDefaultMessage(MessageLoaderParms &parms){
466 chip         1.27 
467 humberto     1.4  		PEG_METHOD_ENTER(TRC_L10N, "MessageLoader::formatDefaultMessage");
468                   		// NOTE TO PROGRAMMERS: using native substitution functions
469                   		// ie. calling Formatter::format()
470 chip         1.27 		// can result in incorrect locale handling of substitutions
471                   
472 humberto     1.4  		// locale INSENSITIVE formatting code
473                   		//cout << "using locale INSENSITIVE formatting" << endl;
474                   		parms.contentlanguages.clear(); // this could have previously been set by ICU
475                   		//cout << parms.toString() << endl;
476                   		//cout << "ml:" << parms.default_msg << endl;
477 kumpf        1.25 		PEG_METHOD_EXIT();
478 humberto     1.4  		return Formatter::format(parms.default_msg,
479                   		 						 	parms.arg0,
480                   								 	parms.arg1,
481 chip         1.27 								 	parms.arg2,
482 humberto     1.4  								 	parms.arg3,
483                   								 	parms.arg4,
484                   								 	parms.arg5,
485                   								 	parms.arg6,
486                   								 	parms.arg7,
487                   								 	parms.arg8,
488                   								 	parms.arg9);
489 chip         1.27 
490 carson.hovey 1.24 
491 humberto     1.4  	}
492 chip         1.27 
493 humberto     1.4  	String MessageLoader::getQualifiedMsgPath(String path){
494 kumpf        1.25 		PEG_METHOD_ENTER(TRC_L10N, "MessageLoader::getQualifiedMsgPath");
495 chip         1.27 
496 humberto     1.4  		if(pegasus_MSG_HOME.size() == 0)
497 joyce.j      1.34 			initPegasusMsgHome(String::EMPTY);
498 chip         1.27 
499                   		if(path.size() == 0)
500 kumpf        1.25 		{
501                   			PEG_METHOD_EXIT();
502 humberto     1.4  			return pegasus_MSG_HOME + server_resbundl_name;
503 kumpf        1.25 		}
504 chip         1.27 
505 humberto     1.4  		Char16 delim = '/'; // NOTE TO PROGRAMMERS: WINDOWS and non-UNIX platforms should redefine delim here
506                   		Uint32 i;
507                   		if(( i = path.find(delim)) != PEG_NOT_FOUND && i == 0){ //  fully qualified package name
508 kumpf        1.25 			PEG_METHOD_EXIT();
509 humberto     1.4  			return path;
510                   		}
511 chip         1.27 
512 kumpf        1.25 		PEG_METHOD_EXIT();
513 humberto     1.4  		return pegasus_MSG_HOME	+ path;  // relative path and package name
514 carson.hovey 1.24 
515 humberto     1.4  	}
516 chip         1.27 
517 humberto     1.4  	void MessageLoader::setPegasusMsgHome(String home){
518                   		PEG_METHOD_ENTER(TRC_L10N, "MessageLoader::setPegasusMsgHome");
519                   			//cout << "MessageLoader::setPegasusMsgHome()" << endl;
520                   			pegasus_MSG_HOME = home + "/";
521 humberto     1.6  			// TODO: remove the next call once test cases are compatible with ICU messages
522                   			checkDefaultMsgLoading();
523 humberto     1.4  		PEG_METHOD_EXIT();
524 chip         1.27 	}
525 joyce.j      1.34     void MessageLoader::setPegasusMsgHomeRelative(const String& argv0)
526                       {
527                   #ifdef PEGASUS_HAS_MESSAGES
528                         try
529                         {
530                           String startingDir, pathDir;
531                   
532                   #ifdef PEGASUS_OS_TYPE_WINDOWS
533                           if(PEG_NOT_FOUND == argv0.find('\\'))
534                           {
535                             char exeDir[_MAX_PATH];
536                             HMODULE module = GetModuleHandle(NULL);
537                             if(NULL != module )
538                             {
539                                 DWORD filename = GetModuleFileName(module,exeDir ,sizeof(exeDir));
540                                  if(0 != filename)
541                                  {
542                                      String path(exeDir);
543                                      Uint32 command = path.reverseFind('\\');
544                                      startingDir = path.subString(0, command+1);
545                                  }
546 joyce.j      1.34           }
547                           }
548                           else
549                           {
550                               Uint32 command = argv0.reverseFind('\\');
551                               startingDir = argv0.subString(0, command+1);
552                           }
553                   #endif
554                   
555                   #ifdef PEGASUS_OS_TYPE_UNIX
556                           if(PEG_NOT_FOUND  != argv0.find('/'))
557                           {
558                               Uint32 command = argv0.reverseFind('/');
559                               startingDir = argv0.subString(0, command+1);
560                           }
561                           else
562                           {
563                             if(FileSystem::existsNoCase(argv0))
564                             {
565                                FileSystem::getCurrentDirectory(startingDir);
566                                startingDir.append("/");
567 joyce.j      1.34           }
568                             else
569                             {
570                              String path;
571                              #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM
572                                #pragma convert(37)
573                                   const char* env = getenv("PATH");
574                                   if(env != NULL)
575                                     EtoA((char*)env);
576                                #pragma convert(0)
577                              #else
578                                   const char* env = getenv("PATH");
579                              #endif
580                              if (env != NULL)
581                                 path.assign(env);
582                              String pathDelim = FileSystem::getPathDelimiter();
583                              Uint32 size = path.size();
584                              while(path.size() > 0)
585                              {
586                                try
587                                {
588 joyce.j      1.34               Uint32 delim = path.find(pathDelim);
589                                 if(delim != PEG_NOT_FOUND)
590                                 {
591                                    pathDir = path.subString(0,delim);
592                                    path.remove(0,(delim+1));
593                                  }
594                                  else
595                                  {
596                                        pathDir = path;
597                                        path = "";
598                                  }
599                                  String commandPath = pathDir.append('/');
600                                  commandPath = commandPath.append(argv0) ;
601                                  Boolean dirContent = FileSystem::existsNoCase(commandPath);
602                                  if(dirContent)
603                                  {
604                                       startingDir = pathDir;
605                                       break;
606                                  }
607                                }
608                                catch(Exception &e)
609 joyce.j      1.34              {
610                                   //Have to do nothing. 
611                                   //Catching the exception if there is any exception while searching in the path variable
612                                }
613                              }
614                             }
615                           }
616                   #endif
617                            initPegasusMsgHome(startingDir);
618                         }
619                         catch(Exception &e)
620                         {
621                                   //Have to do nothing.
622                                   //Catching the exception if there is any exception while searching in the path variable
623                         }
624                   #endif
625                   }
626                   
627                   
628                   void MessageLoader::initPegasusMsgHome(const String & startDir)
629                   {
630 joyce.j      1.34     String startingDir = startDir; 
631                       if (startingDir.size() == 0)
632                       {
633 david        1.15 #ifdef PEGASUS_PLATFORM_OS400_ISERIES_IBM
634                   #pragma convert(37)
635 joyce.j      1.34          const char* env = getenv("PEGASUS_MSG_HOME");
636                               if(env != NULL)
637                                  EtoA((char*)env);
638 david        1.15 #pragma convert(0)
639                   #else
640 joyce.j      1.34         const char* env = getenv("PEGASUS_MSG_HOME");
641 david        1.15 #endif
642 joyce.j      1.34 
643                           if (env != NULL)
644                               startingDir.assign(env);
645                       }
646                   
647 david        1.15 #ifdef PEGASUS_DEFAULT_MESSAGE_SOURCE
648 joyce.j      1.34         if(System::is_absolute_path(
649                                   (const char *)PEGASUS_DEFAULT_MESSAGE_SOURCE))
650                           {
651                               pegasus_MSG_HOME = PEGASUS_DEFAULT_MESSAGE_SOURCE;
652                               pegasus_MSG_HOME.append('/');
653                           }
654                           else
655                           {
656                               if (startingDir.size() != 0)
657                               {
658                                  pegasus_MSG_HOME = startingDir;
659                                   pegasus_MSG_HOME.append('/');
660                               }
661                               pegasus_MSG_HOME.append(PEGASUS_DEFAULT_MESSAGE_SOURCE);
662                               pegasus_MSG_HOME.append('/');
663                           }
664 david        1.15 #else
665 joyce.j      1.34         if (startingDir.size() != 0)
666                           {
667                               pegasus_MSG_HOME = startingDir;
668                               pegasus_MSG_HOME.append("/");
669                           }
670                           else
671                           {
672                                // Will use current working directory
673                           }
674 chip         1.27 #endif
675 joyce.j      1.34         checkDefaultMsgLoading();
676                        }
677 chip         1.27 
678 humberto     1.6  	void MessageLoader::checkDefaultMsgLoading(){
679 chuck        1.13 	  // Note: this function is a special hook for the automated tests (poststarttests)
680                   	  // Since the automated tests expect the old hardcoded default messages, an env var
681                   	  // will be used to tell this code to ignore ICU and return the default message.
682                   	  // This will allow poststarttests to run with ICU installed.
683                   	  // TODO: remove this function once test cases are compatible with ICU messages
684 chuck        1.14 #ifdef PEGASUS_OS_OS400
685                   #pragma convert(37)
686                   #endif
687 chuck        1.13 	  const char* env = getenv("PEGASUS_USE_DEFAULT_MESSAGES");
688 chuck        1.14 #ifdef PEGASUS_OS_OS400
689 chip         1.27 #pragma convert(0)
690                   #endif
691 chuck        1.13 	  if (env != NULL)
692 chip         1.27 	    _useDefaultMsg = true;
693 humberto     1.4  	}
694                   
695 karl         1.20 MessageLoaderParms::MessageLoaderParms()
696                   {
697                   	useProcessLocale = false;
698                   	useThreadLocale = true;
699 chip         1.27 
700 chuck        1.22 #ifdef PEGASUS_HAS_ICU
701 karl         1.20 	useICUfallback = false;
702 chuck        1.22 #endif
703 chip         1.27 
704 karl         1.20 	acceptlanguages = AcceptLanguages();
705                   	contentlanguages = ContentLanguages();
706                   }
707                   
708 chip         1.27 MessageLoaderParms::MessageLoaderParms(
709                       const String& id,
710                       const String& msg,
711                       const Formatter::Arg& arg0,
712 karl         1.20     const Formatter::Arg& arg1,
713                       const Formatter::Arg& arg2,
714                       const Formatter::Arg& arg3,
715                       const Formatter::Arg& arg4,
716                       const Formatter::Arg& arg5,
717                       const Formatter::Arg& arg6,
718                       const Formatter::Arg& arg7,
719                       const Formatter::Arg& arg8,
720                       const Formatter::Arg& arg9)
721                   {
722                       msg_id = id;
723                       default_msg = msg;
724                       _init();
725                       this->arg0 = arg0;
726                       this->arg1 = arg1;
727                       this->arg2 = arg2;
728                       this->arg3 = arg3;
729                       this->arg4 = arg4;
730                       this->arg5 = arg5;
731                       this->arg6 = arg6;
732                       this->arg7 = arg7;
733 karl         1.20     this->arg8 = arg8;
734                       this->arg9 = arg9;
735 chip         1.27 }
736 karl         1.20 
737 chip         1.27 MessageLoaderParms::MessageLoaderParms(
738                       const String& id,
739 karl         1.20     const String& msg)
740                   {
741                       msg_id = id;
742                       default_msg = msg;
743                       _init();
744                   }
745                   
746 chip         1.27 MessageLoaderParms::MessageLoaderParms(
747                       const String& id,
748                       const String& msg,
749 karl         1.20     const Formatter::Arg& arg0)
750                   {
751                       msg_id = id;
752                       default_msg = msg;
753                       _init();
754                       this->arg0 = arg0;
755                   }
756                   
757 chip         1.27 MessageLoaderParms::MessageLoaderParms(
758                       const String& id,
759                       const String& msg,
760 karl         1.20     const Formatter::Arg& arg0,
761                       const Formatter::Arg& arg1)
762                   {
763                       msg_id = id;
764                       default_msg = msg;
765                       _init();
766                       this->arg0 = arg0;
767                       this->arg1 = arg1;
768                   }
769                   
770 chip         1.27 MessageLoaderParms::MessageLoaderParms(
771                       const String& id,
772                       const String& msg,
773 karl         1.20     const Formatter::Arg& arg0,
774                       const Formatter::Arg& arg1,
775                       const Formatter::Arg& arg2)
776                   {
777                       msg_id = id;
778                       default_msg = msg;
779                       _init();
780                       this->arg0 = arg0;
781                       this->arg1 = arg1;
782                       this->arg2 = arg2;
783                   }
784                   
785 chip         1.27 MessageLoaderParms::MessageLoaderParms(
786                       const String& id,
787                       const String& msg,
788 karl         1.20     const Formatter::Arg& arg0,
789                       const Formatter::Arg& arg1,
790                       const Formatter::Arg& arg2,
791                       const Formatter::Arg& arg3)
792                   {
793                       msg_id = id;
794                       default_msg = msg;
795                       _init();
796                       this->arg0 = arg0;
797                       this->arg1 = arg1;
798                       this->arg2 = arg2;
799                       this->arg3 = arg3;
800                   }
801                   
802                   MessageLoaderParms::MessageLoaderParms(
803 chip         1.27     const char* id,
804 karl         1.20     const char* msg)
805                   {
806                       msg_id = id;
807                       default_msg = msg;
808                       _init();
809                   }
810                   
811                   MessageLoaderParms::MessageLoaderParms(
812 chip         1.27     const char* id,
813                       const char* msg,
814 karl         1.20     const String& arg0)
815                   {
816                       msg_id = id;
817                       default_msg = msg;
818                       _init();
819                       this->arg0 = arg0;
820                   }
821                   
822                   MessageLoaderParms::MessageLoaderParms(
823 chip         1.27     const char* id,
824                       const char* msg,
825 karl         1.20     const String& arg0,
826                       const String& arg1)
827                   {
828                       msg_id = id;
829                       default_msg = msg;
830                       _init();
831                       this->arg0 = arg0;
832                       this->arg1 = arg1;
833                   }
834                   
835                   void MessageLoaderParms::_init()
836                   {
837                       useProcessLocale = false;
838                       useThreadLocale = true;
839 chip         1.27 
840 karl         1.20 #ifdef PEGASUS_HAS_ICU
841                       useICUfallback = false;
842                   #endif
843 chip         1.27 
844 karl         1.20     acceptlanguages = AcceptLanguages::EMPTY;
845                       contentlanguages = ContentLanguages::EMPTY;
846                   
847                       this->arg0 = Formatter::DEFAULT_ARG;
848                       this->arg1 = Formatter::DEFAULT_ARG;
849                       this->arg2 = Formatter::DEFAULT_ARG;
850                       this->arg3 = Formatter::DEFAULT_ARG;
851                       this->arg4 = Formatter::DEFAULT_ARG;
852                       this->arg5 = Formatter::DEFAULT_ARG;
853                       this->arg6 = Formatter::DEFAULT_ARG;
854                       this->arg7 = Formatter::DEFAULT_ARG;
855                       this->arg8 = Formatter::DEFAULT_ARG;
856                       this->arg9 = Formatter::DEFAULT_ARG;
857                   }
858                   
859                   String MessageLoaderParms::toString()
860                   {
861                       String s;
862                       String processLoc,threadLoc,ICUfallback;
863                       processLoc = (useProcessLocale) ? "true" : "false";
864                       threadLoc = (useThreadLocale) ? "true" : "false";
865 chuck        1.22 #ifdef PEGASUS_HAS_ICU
866 karl         1.20     ICUfallback = (useICUfallback) ? "true" : "false";
867 chuck        1.22 #endif
868 chip         1.27 
869 karl         1.20     s.append("msg_id = " + msg_id + "\n");
870                       s.append("default_msg = " + default_msg + "\n");
871                       s.append("msg_src_path = " + msg_src_path + "\n");
872                       s.append("acceptlanguages = " + acceptlanguages.toString() + "\n");
873                       s.append("contentlanguages = " + contentlanguages.toString() + "\n");
874 chip         1.27 
875 karl         1.20     s.append("useProcessLocale = " + processLoc + "\n");
876                       s.append("useThreadLocale = " + threadLoc + "\n");
877 chuck        1.22 #ifdef PEGASUS_HAS_ICU
878 karl         1.20     s.append("useICUfallback = " + ICUfallback + "\n");
879 chuck        1.22 #endif
880 chip         1.27     s.append("arg0 = " + arg0.toString() + "\n" + "arg1 = " + arg1.toString() + "\n" + "arg2 = " + arg2.toString() + "\n" + "arg3 = " + arg3.toString() + "\n" +
881                   	      "arg4 = " + arg4.toString() + "\n" + "arg5 = " + arg5.toString() + "\n" + "arg6 = " + arg6.toString() + "\n" + "arg7 = " + arg7.toString() + "\n" +
882 karl         1.20 	      "arg8 = " + arg8.toString() + "\n" + "arg9 = " + arg9.toString() + "\n\n");
883 chip         1.27 
884 karl         1.20     return s;
885                   }
886 humberto     1.4  
887 karl         1.20 MessageLoaderParms::~MessageLoaderParms()
888                   {
889                   }
890 humberto     1.4  
891 karl         1.20 PEGASUS_NAMESPACE_END

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2