sbStringBundleService.cpp
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 :miv */
3 /*
4 //
5 // BEGIN SONGBIRD GPL
6 //
7 // This file is part of the Songbird web player.
8 //
9 // Copyright(c) 2005-2008 POTI, Inc.
10 // http://songbirdnest.com
11 //
12 // This file may be licensed under the terms of of the
13 // GNU General Public License Version 2 (the "GPL").
14 //
15 // Software distributed under the License is distributed
16 // on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, either
17 // express or implied. See the GPL for the specific language
18 // governing rights and limitations.
19 //
20 // You should have received a copy of the GPL along with this
21 // program. If not, go to http://www.gnu.org/licenses/gpl.html
22 // or write to the Free Software Foundation, Inc.,
23 // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
24 //
25 // END SONGBIRD GPL
26 //
27 */
28 
29 //------------------------------------------------------------------------------
30 //------------------------------------------------------------------------------
31 //
32 // Songbird string bundle service.
33 //
34 //------------------------------------------------------------------------------
35 //------------------------------------------------------------------------------
36 
42 //------------------------------------------------------------------------------
43 //
44 // Songbird string bundle service imported services.
45 //
46 //------------------------------------------------------------------------------
47 
48 // Self imports.
49 #include "sbStringBundleService.h"
50 
51 // Mozilla interfaces
52 #include <nsIObserverService.h>
53 
54 // Local imports.
55 #include "sbStringUtils.h"
56 
57 // Mozilla imports.
58 #include <nsAutoPtr.h>
59 #include <nsCOMPtr.h>
60 #include <nsServiceManagerUtils.h>
61 #include <nsThreadUtils.h>
62 
63 //------------------------------------------------------------------------------
64 //
65 // nsISupports implementation.
66 //
67 //------------------------------------------------------------------------------
68 
70  nsIStringBundleService,
73 
74 
75 //------------------------------------------------------------------------------
76 //
77 // sbIStringBundleService implementation.
78 //
79 //------------------------------------------------------------------------------
80 
81 //
82 // Getters/setters.
83 //
84 
85 
89 NS_IMETHODIMP
90 sbStringBundleService::GetBundle(nsIStringBundle** _retval)
91 {
92  NS_ENSURE_ARG_POINTER(_retval);
93  NS_ADDREF(*_retval = mBundle);
94  return NS_OK;
95 }
96 
97 
102 NS_IMETHODIMP
103 sbStringBundleService::GetBrandBundle(nsIStringBundle** _retval)
104 {
105  NS_ENSURE_ARG_POINTER(_retval);
106  NS_ADDREF(*_retval = mBrandBundle);
107  return NS_OK;
108 }
109 
110 
111 //------------------------------------------------------------------------------
112 //
113 // nsIStringBundleService implementation.
114 //
115 //------------------------------------------------------------------------------
116 
126 NS_IMETHODIMP
127 sbStringBundleService::CreateBundle(const char* aURLSpec,
128  nsIStringBundle** _retval)
129 {
130  // Validate arguments.
131  NS_ENSURE_ARG_POINTER(aURLSpec);
132  NS_ENSURE_ARG_POINTER(_retval);
133 
134  // Function variables.
135  nsresult rv;
136 
137  // Get the base string bundle.
138  nsCOMPtr<nsIStringBundle> baseStringBundle;
139  rv = mBaseStringBundleService->CreateBundle(aURLSpec,
140  getter_AddRefs(baseStringBundle));
141  NS_ENSURE_SUCCESS(rv, rv);
142 
143  // Create the Songbird string bundle.
144  nsRefPtr<sbStringBundle> stringBundle;
145  rv = sbStringBundle::New(baseStringBundle, getter_AddRefs(stringBundle));
146  NS_ENSURE_SUCCESS(rv, rv);
147 
148  // Return results.
149  NS_ADDREF(*_retval = stringBundle);
150 
151  return NS_OK;
152 }
153 
154 
163 NS_IMETHODIMP
164 sbStringBundleService::CreateExtensibleBundle(const char *aRegistryKey,
165  nsIStringBundle **_retval)
166 {
167  // Validate arguments.
168  NS_ENSURE_ARG_POINTER(aRegistryKey);
169  NS_ENSURE_ARG_POINTER(_retval);
170 
171  // Function variables.
172  nsresult rv;
173 
174  // Get the base string bundle.
175  nsCOMPtr<nsIStringBundle> baseStringBundle;
176  rv = mBaseStringBundleService->CreateExtensibleBundle
177  (aRegistryKey,
178  getter_AddRefs(baseStringBundle));
179  NS_ENSURE_SUCCESS(rv, rv);
180 
181  // Create the Songbird string bundle.
182  nsRefPtr<sbStringBundle> stringBundle;
183  rv = sbStringBundle::New(baseStringBundle, getter_AddRefs(stringBundle));
184  NS_ENSURE_SUCCESS(rv, rv);
185 
186  // Return results.
187  NS_ADDREF(*_retval = stringBundle);
188 
189  return NS_OK;
190 }
191 
192 
202 NS_IMETHODIMP
203 sbStringBundleService::FormatStatusMessage(nsresult aStatus,
204  const PRUnichar *aStatusArg,
205  PRUnichar **_retval)
206 {
207  return mBaseStringBundleService->FormatStatusMessage(aStatus,
208  aStatusArg,
209  _retval);
210 }
211 
212 
223 NS_IMETHODIMP
224 sbStringBundleService::FlushBundles()
225 {
226  return mBaseStringBundleService->FlushBundles();
227 }
228 
229 
230 //------------------------------------------------------------------------------
231 //
232 // nsIObserver implementation.
233 //
234 //------------------------------------------------------------------------------
235 
236 NS_IMETHODIMP
237 sbStringBundleService::Observe(nsISupports *aSubject,
238  const char *aTopic,
239  const PRUnichar *someData)
240 {
241  nsresult rv;
242  if (!strcmp("chrome-flush-caches", aTopic)) {
243  // the selected locale may have changed, reload the bundles
244  rv = ReloadBundles();
245  NS_ENSURE_SUCCESS(rv, rv);
246  }
247  else if (!strcmp("profile-change-teardown", aTopic)) {
248  nsCOMPtr<nsIObserverService> obssvc =
249  do_GetService("@mozilla.org/observer-service;1", &rv);
250  NS_ENSURE_SUCCESS(rv, rv);
251  rv = obssvc->RemoveObserver(this, "chrome-flush-caches");
252  NS_ENSURE_SUCCESS(rv, rv);
253  rv = obssvc->RemoveObserver(this, aTopic);
254  NS_ENSURE_SUCCESS(rv, rv);
255  }
256  return NS_OK;
257 }
258 
259 
260 //------------------------------------------------------------------------------
261 //
262 // Public services.
263 //
264 //------------------------------------------------------------------------------
265 
271 {
272 }
273 
274 
280 {
281 }
282 
283 
287 nsresult
289 {
290  nsresult rv;
291 
292  // Hook up the observer to be notified when the locale needs to change
293  nsCOMPtr<nsIObserverService> obssvc =
294  do_GetService("@mozilla.org/observer-service;1", &rv);
295  NS_ENSURE_SUCCESS(rv, rv);
296  rv = obssvc->AddObserver(this, "chrome-flush-caches", PR_FALSE);
297  NS_ENSURE_SUCCESS(rv, rv);
298  rv = obssvc->AddObserver(this, "profile-change-teardown", PR_FALSE);
299  NS_ENSURE_SUCCESS(rv, rv);
300 
301  rv = ReloadBundles();
302  NS_ENSURE_SUCCESS(rv, rv);
303 
304  return NS_OK;
305 }
306 
307 
311 nsresult
313 {
314  nsresult rv;
315 
316  // Get the base string bundle service.
317  mBaseStringBundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
318  NS_ENSURE_SUCCESS(rv, rv);
319 
320  // Get the main Songbird string bundle.
321  rv = CreateBundle("chrome://songbird/locale/songbird.properties",
322  getter_AddRefs(mBundle));
323  NS_ENSURE_SUCCESS(rv, rv);
324 
325  // Get the main Songbird string bundle.
326  rv = CreateBundle("chrome://branding/locale/brand.properties",
327  getter_AddRefs(mBrandBundle));
328  NS_ENSURE_SUCCESS(rv, rv);
329 
330  return NS_OK;
331 }
332 
333 
334 //------------------------------------------------------------------------------
335 //------------------------------------------------------------------------------
336 //
337 // Songbird string bundle class implementation.
338 //
339 //------------------------------------------------------------------------------
340 //------------------------------------------------------------------------------
341 
342 //------------------------------------------------------------------------------
343 //
344 // Songbird string bundle nsISupports implementation.
345 //
346 //------------------------------------------------------------------------------
347 
349  nsIStringBundle)
350 
351 
352 //------------------------------------------------------------------------------
353 //
354 // Songbird string bundle nsIStringBundle implementation.
355 //
356 //------------------------------------------------------------------------------
357 
358 //
359 // wstring GetStringFromID (in long aID);
360 //
361 
362 NS_IMETHODIMP
363 sbStringBundle::GetStringFromID(PRInt32 aID,
364  PRUnichar **_retval)
365 {
366  // Validate arguments.
367  NS_ENSURE_ARG_POINTER(_retval);
368 
369  // Function variables.
370  nsresult rv;
371 
372  // Get the string from the bundle list.
373  nsAutoString bundleString;
374  PRBool bundleAvailable = PR_FALSE;
375  PRUint32 bundleCount = mStringBundleList.Count();
376  for (PRUint32 i = 0; i < bundleCount; i++) {
377  nsCOMPtr<nsIStringBundle> stringBundle = mStringBundleList[i];
378  rv = stringBundle->GetStringFromID(aID, getter_Copies(bundleString));
379  if (NS_SUCCEEDED(rv)) {
380  bundleAvailable = PR_TRUE;
381  break;
382  }
383  }
384  if (!bundleAvailable)
385  return NS_ERROR_NOT_AVAILABLE;
386 
387  // Apply string substitutions.
388  rv = ApplySubstitutions(bundleString);
389  NS_ENSURE_SUCCESS(rv, rv);
390 
391  // Return results.
392  PRUnichar* prBundleString = ToNewUnicode(bundleString);
393  NS_ENSURE_TRUE(prBundleString, NS_ERROR_OUT_OF_MEMORY);
394  *_retval = prBundleString;
395 
396  return NS_OK;
397 }
398 
399 
400 //
401 // wstring GetStringFromName (in wstring aName);
402 //
403 
404 NS_IMETHODIMP
405 sbStringBundle::GetStringFromName(const PRUnichar *aName,
406  PRUnichar **_retval)
407 {
408  // Validate arguments.
409  NS_ENSURE_ARG_POINTER(aName);
410  NS_ENSURE_ARG_POINTER(_retval);
411 
412  // Function variables.
413  nsresult rv;
414 
415  // Get the string from the bundle list.
416  nsAutoString bundleString;
417  PRBool bundleAvailable = PR_FALSE;
418  PRUint32 bundleCount = mStringBundleList.Count();
419  for (PRUint32 i = 0; i < bundleCount; i++) {
420  nsCOMPtr<nsIStringBundle> stringBundle = mStringBundleList[i];
421  rv = stringBundle->GetStringFromName(aName, getter_Copies(bundleString));
422  if (NS_SUCCEEDED(rv)) {
423  bundleAvailable = PR_TRUE;
424  break;
425  }
426  }
427  if (!bundleAvailable)
428  return NS_ERROR_NOT_AVAILABLE;
429 
430  // Apply string substitutions.
431  rv = ApplySubstitutions(bundleString);
432  NS_ENSURE_SUCCESS(rv, rv);
433 
434  // Return results.
435  PRUnichar* prBundleString = ToNewUnicode(bundleString);
436  NS_ENSURE_TRUE(prBundleString, NS_ERROR_OUT_OF_MEMORY);
437  *_retval = prBundleString;
438 
439  return NS_OK;
440 }
441 
442 
443 //
444 // wstring formatStringFromID (in long aID,
445 // [array, size_is (length)] in wstring params,
446 // in unsigned long length);
447 //
448 
449 NS_IMETHODIMP
450 sbStringBundle::FormatStringFromID(PRInt32 aID,
451  const PRUnichar **params,
452  PRUint32 length,
453  PRUnichar **_retval)
454 {
455  // Validate arguments.
456  NS_ENSURE_ARG_POINTER(_retval);
457 
458  // Function variables.
459  nsresult rv;
460 
461  // Get the string from the bundle list.
462  nsAutoString bundleString;
463  PRBool bundleAvailable = PR_FALSE;
464  PRUint32 bundleCount = mStringBundleList.Count();
465  for (PRUint32 i = 0; i < bundleCount; i++) {
466  nsCOMPtr<nsIStringBundle> stringBundle = mStringBundleList[i];
467  rv = stringBundle->FormatStringFromID(aID,
468  params,
469  length,
470  getter_Copies(bundleString));
471  if (NS_SUCCEEDED(rv)) {
472  bundleAvailable = PR_TRUE;
473  break;
474  }
475  }
476  if (!bundleAvailable)
477  return NS_ERROR_NOT_AVAILABLE;
478 
479  // Apply string substitutions.
480  rv = ApplySubstitutions(bundleString);
481  NS_ENSURE_SUCCESS(rv, rv);
482 
483  // Return results.
484  PRUnichar* prBundleString = ToNewUnicode(bundleString);
485  NS_ENSURE_TRUE(prBundleString, NS_ERROR_OUT_OF_MEMORY);
486  *_retval = prBundleString;
487 
488  return NS_OK;
489 }
490 
491 
492 //
493 // wstring formatStringFromName (in wstring aName,
494 // [array, size_is (length)] in wstring params,
495 // in unsigned long length);
496 //
497 
498 NS_IMETHODIMP
499 sbStringBundle::FormatStringFromName(const PRUnichar *aName,
500  const PRUnichar **params,
501  PRUint32 length,
502  PRUnichar **_retval)
503 {
504  // Validate arguments.
505  NS_ENSURE_ARG_POINTER(aName);
506  NS_ENSURE_ARG_POINTER(_retval);
507 
508  // Function variables.
509  nsresult rv;
510 
511  // Get the string from the bundle list.
512  nsAutoString bundleString;
513  PRBool bundleAvailable = PR_FALSE;
514  PRUint32 bundleCount = mStringBundleList.Count();
515  for (PRUint32 i = 0; i < bundleCount; i++) {
516  nsCOMPtr<nsIStringBundle> stringBundle = mStringBundleList[i];
517  rv = stringBundle->FormatStringFromName(aName,
518  params,
519  length,
520  getter_Copies(bundleString));
521  if (NS_SUCCEEDED(rv)) {
522  bundleAvailable = PR_TRUE;
523  break;
524  }
525  }
526  if (!bundleAvailable)
527  return NS_ERROR_NOT_AVAILABLE;
528 
529  // Apply string substitutions.
530  rv = ApplySubstitutions(bundleString);
531  NS_ENSURE_SUCCESS(rv, rv);
532 
533  // Return results.
534  PRUnichar* prBundleString = ToNewUnicode(bundleString);
535  NS_ENSURE_TRUE(prBundleString, NS_ERROR_OUT_OF_MEMORY);
536  *_retval = prBundleString;
537 
538  return NS_OK;
539 }
540 
541 
542 //
543 // nsISimpleEnumerator getSimpleEnumeration ();
544 //
545 
546 NS_IMETHODIMP
547 sbStringBundle::GetSimpleEnumeration(nsISimpleEnumerator **_retval)
548 {
549  return mBaseStringBundle->GetSimpleEnumeration(_retval);
550 }
551 
552 
553 //------------------------------------------------------------------------------
554 //
555 // Public Songbird string bundle services.
556 //
557 //------------------------------------------------------------------------------
558 
568 /* static */ nsresult
569 sbStringBundle::New(nsIStringBundle* aBaseStringBundle,
570  sbStringBundle** aStringBundle)
571 {
572  // Validate arguments.
573  NS_ENSURE_ARG_POINTER(aBaseStringBundle);
574  NS_ENSURE_ARG_POINTER(aStringBundle);
575 
576  // Function variables.
577  nsresult rv;
578 
579  // Create the instance.
580  nsRefPtr<sbStringBundle> stringBundle = new sbStringBundle(aBaseStringBundle);
581  NS_ENSURE_TRUE(stringBundle, NS_ERROR_OUT_OF_MEMORY);
582 
583  // Initialize the instance.
584  rv = stringBundle->Initialize();
585  NS_ENSURE_SUCCESS(rv, rv);
586 
587  // Return results.
588  stringBundle.forget(aStringBundle);
589 
590  return NS_OK;
591 }
592 
593 
599 {
600 }
601 
602 
603 //------------------------------------------------------------------------------
604 //
605 // Private Songbird string bundle services.
606 //
607 //------------------------------------------------------------------------------
608 
616 sbStringBundle::sbStringBundle(nsIStringBundle* aBaseStringBundle) :
617  mBaseStringBundle(aBaseStringBundle)
618 {
619 }
620 
621 
626 nsresult
627 sbStringBundle::Initialize()
628 {
629  nsresult rv;
630 
631  // Get the base string bundle service.
632  mBaseStringBundleService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
633  NS_ENSURE_SUCCESS(rv, rv);
634 
635  // Load the string bundle.
636  rv = LoadBundle(mBaseStringBundle);
637  NS_ENSURE_SUCCESS(rv, rv);
638 
639  return NS_OK;
640 }
641 
642 
650 nsresult
651 sbStringBundle::LoadBundle(nsAString& aBundleURLSpec)
652 {
653  nsresult rv;
654 
655  // Create a new bundle.
656  nsCOMPtr<nsIStringBundle> bundle;
657  rv = mBaseStringBundleService->CreateBundle
658  (NS_ConvertUTF16toUTF8(aBundleURLSpec).BeginReading(),
659  getter_AddRefs(bundle));
660  NS_ENSURE_SUCCESS(rv, rv);
661 
662  // Load the bundle.
663  rv = LoadBundle(bundle);
664  NS_ENSURE_SUCCESS(rv, rv);
665 
666  return NS_OK;
667 }
668 
669 
676 nsresult
677 sbStringBundle::LoadBundle(nsIStringBundle* aBundle)
678 {
679  // Validate arguments.
680  NS_ENSURE_ARG_POINTER(aBundle);
681 
682  // Function variables.
683  nsresult rv;
684 
685  // Add the string bundle to the list of string bundles.
686  mStringBundleList.AppendObject(aBundle);
687 
688  // Get the list of included string bundles.
689  nsTArray<nsString> includeBundleList;
690  nsAutoString includeBundleListString;
691  rv = aBundle->GetStringFromName
692  (NS_LITERAL_STRING("include_bundle_list").get(),
693  getter_Copies(includeBundleListString));
694  if (NS_SUCCEEDED(rv)) {
695  nsString_Split(includeBundleListString,
696  NS_LITERAL_STRING(","),
697  includeBundleList);
698  }
699 
700  // Load each of the included string bundles.
701  PRUint32 bundleCount = includeBundleList.Length();
702  for (PRUint32 i = 0; i < bundleCount; i++) {
703  rv = LoadBundle(includeBundleList[i]);
704  NS_ENSURE_SUCCESS(rv, rv);
705  }
706 
707  return NS_OK;
708 }
709 
710 
717 nsresult
718 sbStringBundle::ApplySubstitutions(nsAString& aString)
719 {
720  nsresult rv;
721 
722  // Apply embedded bundle strings.
723  nsAutoString processedString(aString);
724  PRInt32 subStartIndex = 0;
725  PRInt32 subEndIndex = -1;
726  while (1) {
727  // Find the next embedded bundle string.
728  PRInt32 subLength;
729  subStartIndex = processedString.Find("&",
730  static_cast<PRUint32>(subStartIndex));
731  if (subStartIndex < 0)
732  break;
733  subEndIndex = processedString.Find(";",
734  static_cast<PRUint32>(subStartIndex));
735  if (subEndIndex < 0)
736  break;
737  subLength = subEndIndex + 1 - subStartIndex;
738 
739  // Get the bundle string name.
740  nsAutoString subName(Substring(processedString,
741  subStartIndex + 1,
742  subLength - 2));
743 
744  // Get the bundle string, special casing "&amp;".
745  nsAutoString subString;
746  if (subName.Equals(NS_LITERAL_STRING("amp"))) {
747  subString.Assign(NS_LITERAL_STRING("&"));
748  } else {
749  rv = GetStringFromName(subName.get(), getter_Copies(subString));
750  if (NS_FAILED(rv))
751  subString.Truncate();
752  }
753 
754  // Apply the embedded bundle string.
755  processedString.Replace(subStartIndex, subLength, subString);
756 
757  // Continue processing after the bundle string.
758  subStartIndex += subString.Length();
759  }
760 
761  // Return results.
762  aString.Assign(processedString);
763 
764  return NS_OK;
765 }
766 
return NS_OK
NS_IMPL_THREADSAFE_ISUPPORTS1(sbStringBundle, nsIStringBundle) NS_IMETHODIMP sbStringBundle
NS_DECL_ISUPPORTS NS_DECL_NSISTRINGBUNDLESERVICE NS_DECL_NSIOBSERVER NS_DECL_SBISTRINGBUNDLESERVICE sbStringBundleService()
var bundle
void nsString_Split(const nsAString &aString, const nsAString &aDelimiter, nsTArray< nsString > &aSubStringArray)
NS_DECL_ISUPPORTS static NS_DECL_NSISTRINGBUNDLE nsresult New(nsIStringBundle *aBaseStringBundle, sbStringBundle **aStringBundle)
_updateCookies aName
Songbird String Bundle Service Definitions.
Interface for the Songbird string bundle service. Instantiate as a component service.
_getSelectedPageStyle s i
NS_IMPL_THREADSAFE_ISUPPORTS3(sbStringBundleService, nsIStringBundleService, nsIObserver, sbIStringBundleService) NS_IMETHODIMP sbStringBundleService
Main Songbird string bundle. Thread-safe.