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

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

No CVS admin address has been configured
Powered by
ViewCVS 0.9.2