DirectoryProvider.cpp 4.81 KB
Newer Older
1
2
3
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
4

5
#include "DirectoryProvider.h"
6
7
8

#include "nsIFile.h"
#include "nsISimpleEnumerator.h"
9
10
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
11

12
13
#include "nsArrayEnumerator.h"
#include "nsEnumeratorUtils.h"
14
#include "nsAppDirectoryServiceDefs.h"
15
#include "nsDirectoryServiceDefs.h"
16
#include "nsCategoryManagerUtils.h"
17
#include "nsComponentManagerUtils.h"
18
#include "nsCOMArray.h"
19
#include "nsDirectoryServiceUtils.h"
20
#include "mozilla/ModuleUtils.h"
21
#include "mozilla/intl/LocaleService.h"
22
#include "nsServiceManagerUtils.h"
23
#include "nsString.h"
24
25
#include "nsXULAppAPI.h"

26
27
using mozilla::intl::LocaleService;

28
29
namespace mozilla {
namespace browser {
30

31
NS_IMPL_ISUPPORTS(DirectoryProvider, nsIDirectoryServiceProvider,
32
                  nsIDirectoryServiceProvider2)
33
34

NS_IMETHODIMP
35
36
DirectoryProvider::GetFile(const char* aKey, bool* aPersist,
                           nsIFile** aResult) {
37
  return NS_ERROR_FAILURE;
38
39
}

40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// Appends the distribution-specific search engine directories to the
// array.  The directory structure is as follows:

// appdir/
// \- distribution/
//    \- searchplugins/
//       |- common/
//       \- locale/
//          |- <locale 1>/
//          ...
//          \- <locale N>/

// common engines are loaded for all locales.  If there is no locale
// directory for the current locale, there is a pref:
// "distribution.searchplugins.defaultLocale"
// which specifies a default locale to use.

57
58
static void AppendDistroSearchDirs(nsIProperties* aDirSvc,
                                   nsCOMArray<nsIFile>& array) {
59
  nsCOMPtr<nsIFile> searchPlugins;
60
  nsresult rv = aDirSvc->Get(XRE_APP_DISTRIBUTION_DIR, NS_GET_IID(nsIFile),
61
                             getter_AddRefs(searchPlugins));
62
  if (NS_FAILED(rv)) return;
63
  searchPlugins->AppendNative("searchplugins"_ns);
64
65
66
67

  nsCOMPtr<nsIFile> commonPlugins;
  rv = searchPlugins->Clone(getter_AddRefs(commonPlugins));
  if (NS_SUCCEEDED(rv)) {
68
    commonPlugins->AppendNative("common"_ns);
69
    array.AppendObject(commonPlugins);
70
71
72
73
74
75
  }

  nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
  if (prefs) {
    nsCOMPtr<nsIFile> localePlugins;
    rv = searchPlugins->Clone(getter_AddRefs(localePlugins));
76
    if (NS_FAILED(rv)) return;
77

78
    localePlugins->AppendNative("locale"_ns);
79

80
    nsAutoCString defLocale;
81
    rv = prefs->GetCharPref("distribution.searchplugins.defaultLocale",
82
                            defLocale);
83
84
85
86
87
    if (NS_SUCCEEDED(rv)) {
      nsCOMPtr<nsIFile> defLocalePlugins;
      rv = localePlugins->Clone(getter_AddRefs(defLocalePlugins));
      if (NS_SUCCEEDED(rv)) {
        defLocalePlugins->AppendNative(defLocale);
88
89
        array.AppendObject(defLocalePlugins);
        return;  // all done
90
91
92
93
      }
    }

    // we didn't have a defaultLocale, use the user agent locale
94
    nsAutoCString locale;
95
    LocaleService::GetInstance()->GetAppLocaleAsBCP47(locale);
96

97
98
    nsCOMPtr<nsIFile> curLocalePlugins;
    rv = localePlugins->Clone(getter_AddRefs(curLocalePlugins));
99
    if (NS_SUCCEEDED(rv)) {
100
      curLocalePlugins->AppendNative(locale);
101
102
      array.AppendObject(curLocalePlugins);
      return;  // all done
103
104
105
106
    }
  }
}

107
NS_IMETHODIMP
108
DirectoryProvider::GetFiles(const char* aKey, nsISimpleEnumerator** aResult) {
109
  if (!strcmp(aKey, NS_APP_DISTRIBUTION_SEARCH_DIR_LIST)) {
110
111
112
    nsCOMPtr<nsIProperties> dirSvc(
        do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
    if (!dirSvc) return NS_ERROR_FAILURE;
113
114
115
116

    nsCOMArray<nsIFile> distroFiles;
    AppendDistroSearchDirs(dirSvc, distroFiles);

117
    return NS_NewArrayEnumerator(aResult, distroFiles, NS_GET_IID(nsIFile));
118
119
  }

120
121
122
123
  return NS_ERROR_FAILURE;
}

NS_IMETHODIMP
124
DirectoryProvider::AppendingEnumerator::HasMoreElements(bool* aResult) {
125
  *aResult = mNext ? true : false;
126
127
128
129
  return NS_OK;
}

NS_IMETHODIMP
130
DirectoryProvider::AppendingEnumerator::GetNext(nsISupports** aResult) {
131
  if (aResult) NS_ADDREF(*aResult = mNext);
132

133
  mNext = nullptr;
134
135
136

  // Ignore all errors

137
  bool more;
138
139
140
141
142
  while (NS_SUCCEEDED(mBase->HasMoreElements(&more)) && more) {
    nsCOMPtr<nsISupports> nextbasesupp;
    mBase->GetNext(getter_AddRefs(nextbasesupp));

    nsCOMPtr<nsIFile> nextbase(do_QueryInterface(nextbasesupp));
143
    if (!nextbase) continue;
144
145

    nextbase->Clone(getter_AddRefs(mNext));
146
    if (!mNext) continue;
147

148
    char const* const* i = mAppendList;
149
150
151
152
153
    while (*i) {
      mNext->AppendNative(nsDependentCString(*i));
      ++i;
    }

154
    mNext = nullptr;
155
156
157
158
159
  }

  return NS_OK;
}

160
DirectoryProvider::AppendingEnumerator::AppendingEnumerator(
161
    nsISimpleEnumerator* aBase, char const* const* aAppendList)
162
    : mBase(aBase), mAppendList(aAppendList) {
163
  // Initialize mNext to begin.
164
  GetNext(nullptr);
165
}
166

167
168
}  // namespace browser
}  // namespace mozilla