browser/components/dirprovider/DirectoryProvider.cpp

Fri, 16 Jan 2015 18:13:44 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Fri, 16 Jan 2015 18:13:44 +0100
branch
TOR_BUG_9701
changeset 14
925c144e1f1f
permissions
-rw-r--r--

Integrate suggestion from review to improve consistency with existing code.

     1 /* This Source Code Form is subject to the terms of the Mozilla Public
     2  * License, v. 2.0. If a copy of the MPL was not distributed with this
     3  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     5 #include "nsIDirectoryService.h"
     6 #include "DirectoryProvider.h"
     8 #include "nsIFile.h"
     9 #include "nsISimpleEnumerator.h"
    10 #include "nsIPrefService.h"
    11 #include "nsIPrefBranch.h"
    13 #include "nsArrayEnumerator.h"
    14 #include "nsEnumeratorUtils.h"
    15 #include "nsAppDirectoryServiceDefs.h"
    16 #include "nsDirectoryServiceDefs.h"
    17 #include "nsCategoryManagerUtils.h"
    18 #include "nsComponentManagerUtils.h"
    19 #include "nsCOMArray.h"
    20 #include "nsDirectoryServiceUtils.h"
    21 #include "mozilla/ModuleUtils.h"
    22 #include "nsServiceManagerUtils.h"
    23 #include "nsStringAPI.h"
    24 #include "nsXULAppAPI.h"
    25 #include "nsIPrefLocalizedString.h"
    27 namespace mozilla {
    28 namespace browser {
    30 NS_IMPL_ISUPPORTS(DirectoryProvider,
    31                   nsIDirectoryServiceProvider,
    32                   nsIDirectoryServiceProvider2)
    34 NS_IMETHODIMP
    35 DirectoryProvider::GetFile(const char *aKey, bool *aPersist, nsIFile* *aResult)
    36 {
    37   nsresult rv;
    39   *aResult = nullptr;
    41   // NOTE: This function can be reentrant through the NS_GetSpecialDirectory
    42   // call, so be careful not to cause infinite recursion.
    44   nsCOMPtr<nsIFile> file;
    46   char const* leafName = nullptr;
    48   if (!strcmp(aKey, NS_APP_BOOKMARKS_50_FILE)) {
    49     leafName = "bookmarks.html";
    51     nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
    52     if (prefs) {
    53       nsCString path;
    54       rv = prefs->GetCharPref("browser.bookmarks.file", getter_Copies(path));
    55       if (NS_SUCCEEDED(rv)) {
    56         NS_NewNativeLocalFile(path, true, getter_AddRefs(file));
    57       }
    58     }
    59   }
    60   else {
    61     return NS_ERROR_FAILURE;
    62   }
    64   nsDependentCString leafstr(leafName);
    66   nsCOMPtr<nsIFile> parentDir;
    67   if (file) {
    68     rv = file->GetParent(getter_AddRefs(parentDir));
    69     if (NS_FAILED(rv))
    70       return rv;
    71   }
    72   else {
    73     rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(parentDir));
    74     if (NS_FAILED(rv))
    75       return rv;
    77     rv = parentDir->Clone(getter_AddRefs(file));
    78     if (NS_FAILED(rv))
    79       return rv;
    81     file->AppendNative(leafstr);
    82   }
    84   *aPersist = true;
    85   NS_ADDREF(*aResult = file);
    87   return NS_OK;
    88 }
    90 static void
    91 AppendFileKey(const char *key, nsIProperties* aDirSvc,
    92               nsCOMArray<nsIFile> &array)
    93 {
    94   nsCOMPtr<nsIFile> file;
    95   nsresult rv = aDirSvc->Get(key, NS_GET_IID(nsIFile), getter_AddRefs(file));
    96   if (NS_FAILED(rv))
    97     return;
    99   bool exists;
   100   rv = file->Exists(&exists);
   101   if (NS_FAILED(rv) || !exists)
   102     return;
   104   array.AppendObject(file);
   105 }
   107 // Appends the distribution-specific search engine directories to the
   108 // array.  The directory structure is as follows:
   110 // appdir/
   111 // \- distribution/
   112 //    \- searchplugins/
   113 //       |- common/
   114 //       \- locale/
   115 //          |- <locale 1>/
   116 //          ...
   117 //          \- <locale N>/
   119 // common engines are loaded for all locales.  If there is no locale
   120 // directory for the current locale, there is a pref:
   121 // "distribution.searchplugins.defaultLocale"
   122 // which specifies a default locale to use.
   124 static void
   125 AppendDistroSearchDirs(nsIProperties* aDirSvc, nsCOMArray<nsIFile> &array)
   126 {
   127   nsCOMPtr<nsIFile> searchPlugins;
   128   nsresult rv = aDirSvc->Get(XRE_EXECUTABLE_FILE,
   129                              NS_GET_IID(nsIFile),
   130                              getter_AddRefs(searchPlugins));
   131   if (NS_FAILED(rv))
   132     return;
   133   searchPlugins->SetNativeLeafName(NS_LITERAL_CSTRING("distribution"));
   134   searchPlugins->AppendNative(NS_LITERAL_CSTRING("searchplugins"));
   136   bool exists;
   137   rv = searchPlugins->Exists(&exists);
   138   if (NS_FAILED(rv) || !exists)
   139     return;
   141   nsCOMPtr<nsIFile> commonPlugins;
   142   rv = searchPlugins->Clone(getter_AddRefs(commonPlugins));
   143   if (NS_SUCCEEDED(rv)) {
   144     commonPlugins->AppendNative(NS_LITERAL_CSTRING("common"));
   145     rv = commonPlugins->Exists(&exists);
   146     if (NS_SUCCEEDED(rv) && exists)
   147         array.AppendObject(commonPlugins);
   148   }
   150   nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
   151   if (prefs) {
   153     nsCOMPtr<nsIFile> localePlugins;
   154     rv = searchPlugins->Clone(getter_AddRefs(localePlugins));
   155     if (NS_FAILED(rv))
   156       return;
   158     localePlugins->AppendNative(NS_LITERAL_CSTRING("locale"));
   160     nsCString locale;
   161     nsCOMPtr<nsIPrefLocalizedString> prefString;
   162     rv = prefs->GetComplexValue("general.useragent.locale",
   163                                 NS_GET_IID(nsIPrefLocalizedString),
   164                                 getter_AddRefs(prefString));
   165     if (NS_SUCCEEDED(rv)) {
   166       nsAutoString wLocale;
   167       prefString->GetData(getter_Copies(wLocale));
   168       CopyUTF16toUTF8(wLocale, locale);
   169     } else {
   170       rv = prefs->GetCharPref("general.useragent.locale", getter_Copies(locale));
   171     }
   173     if (NS_SUCCEEDED(rv)) {
   175       nsCOMPtr<nsIFile> curLocalePlugins;
   176       rv = localePlugins->Clone(getter_AddRefs(curLocalePlugins));
   177       if (NS_SUCCEEDED(rv)) {
   179         curLocalePlugins->AppendNative(locale);
   180         rv = curLocalePlugins->Exists(&exists);
   181         if (NS_SUCCEEDED(rv) && exists) {
   182           array.AppendObject(curLocalePlugins);
   183           return; // all done
   184         }
   185       }
   186     }
   188     // we didn't append the locale dir - try the default one
   189     nsCString defLocale;
   190     rv = prefs->GetCharPref("distribution.searchplugins.defaultLocale",
   191                             getter_Copies(defLocale));
   192     if (NS_SUCCEEDED(rv)) {
   194       nsCOMPtr<nsIFile> defLocalePlugins;
   195       rv = localePlugins->Clone(getter_AddRefs(defLocalePlugins));
   196       if (NS_SUCCEEDED(rv)) {
   198         defLocalePlugins->AppendNative(defLocale);
   199         rv = defLocalePlugins->Exists(&exists);
   200         if (NS_SUCCEEDED(rv) && exists)
   201           array.AppendObject(defLocalePlugins);
   202       }
   203     }
   204   }
   205 }
   207 NS_IMETHODIMP
   208 DirectoryProvider::GetFiles(const char *aKey, nsISimpleEnumerator* *aResult)
   209 {
   210   nsresult rv;
   212   if (!strcmp(aKey, NS_APP_SEARCH_DIR_LIST)) {
   213     nsCOMPtr<nsIProperties> dirSvc
   214       (do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
   215     if (!dirSvc)
   216       return NS_ERROR_FAILURE;
   218     nsCOMArray<nsIFile> baseFiles;
   220     /**
   221      * We want to preserve the following order, since the search service loads
   222      * engines in first-loaded-wins order.
   223      *   - extension search plugin locations (prepended below using
   224      *     NS_NewUnionEnumerator)
   225      *   - distro search plugin locations
   226      *   - user search plugin locations (profile)
   227      *   - app search plugin location (shipped engines)
   228      */
   229     AppendDistroSearchDirs(dirSvc, baseFiles);
   230     AppendFileKey(NS_APP_USER_SEARCH_DIR, dirSvc, baseFiles);
   231     AppendFileKey(NS_APP_SEARCH_DIR, dirSvc, baseFiles);
   233     nsCOMPtr<nsISimpleEnumerator> baseEnum;
   234     rv = NS_NewArrayEnumerator(getter_AddRefs(baseEnum), baseFiles);
   235     if (NS_FAILED(rv))
   236       return rv;
   238     nsCOMPtr<nsISimpleEnumerator> list;
   239     rv = dirSvc->Get(XRE_EXTENSIONS_DIR_LIST,
   240                      NS_GET_IID(nsISimpleEnumerator), getter_AddRefs(list));
   241     if (NS_FAILED(rv))
   242       return rv;
   244     static char const *const kAppendSPlugins[] = {"searchplugins", nullptr};
   246     nsCOMPtr<nsISimpleEnumerator> extEnum =
   247       new AppendingEnumerator(list, kAppendSPlugins);
   248     if (!extEnum)
   249       return NS_ERROR_OUT_OF_MEMORY;
   251     return NS_NewUnionEnumerator(aResult, extEnum, baseEnum);
   252   }
   254   return NS_ERROR_FAILURE;
   255 }
   257 NS_IMPL_ISUPPORTS(DirectoryProvider::AppendingEnumerator, nsISimpleEnumerator)
   259 NS_IMETHODIMP
   260 DirectoryProvider::AppendingEnumerator::HasMoreElements(bool *aResult)
   261 {
   262   *aResult = mNext ? true : false;
   263   return NS_OK;
   264 }
   266 NS_IMETHODIMP
   267 DirectoryProvider::AppendingEnumerator::GetNext(nsISupports* *aResult)
   268 {
   269   if (aResult)
   270     NS_ADDREF(*aResult = mNext);
   272   mNext = nullptr;
   274   nsresult rv;
   276   // Ignore all errors
   278   bool more;
   279   while (NS_SUCCEEDED(mBase->HasMoreElements(&more)) && more) {
   280     nsCOMPtr<nsISupports> nextbasesupp;
   281     mBase->GetNext(getter_AddRefs(nextbasesupp));
   283     nsCOMPtr<nsIFile> nextbase(do_QueryInterface(nextbasesupp));
   284     if (!nextbase)
   285       continue;
   287     nextbase->Clone(getter_AddRefs(mNext));
   288     if (!mNext)
   289       continue;
   291     char const *const * i = mAppendList;
   292     while (*i) {
   293       mNext->AppendNative(nsDependentCString(*i));
   294       ++i;
   295     }
   297     bool exists;
   298     rv = mNext->Exists(&exists);
   299     if (NS_SUCCEEDED(rv) && exists)
   300       break;
   302     mNext = nullptr;
   303   }
   305   return NS_OK;
   306 }
   308 DirectoryProvider::AppendingEnumerator::AppendingEnumerator
   309     (nsISimpleEnumerator* aBase,
   310      char const *const *aAppendList) :
   311   mBase(aBase),
   312   mAppendList(aAppendList)
   313 {
   314   // Initialize mNext to begin.
   315   GetNext(nullptr);
   316 }
   318 } // namespace browser
   319 } // namespace mozilla

mercurial