1 // Copyright (c) 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/common/extensions/api/i18n/default_locale_handler.h"
7 #include "base/file_util.h"
8 #include "base/files/file_enumerator.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/stringprintf.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/values.h"
14 #include "extensions/common/constants.h"
15 #include "extensions/common/extension_l10n_util.h"
16 #include "extensions/common/manifest.h"
17 #include "extensions/common/manifest_constants.h"
18 #include "grit/extensions_strings.h"
19 #include "ui/base/l10n/l10n_util.h"
21 namespace extensions
{
23 namespace keys
= manifest_keys
;
24 namespace errors
= manifest_errors
;
27 const std::string
& LocaleInfo::GetDefaultLocale(const Extension
* extension
) {
28 LocaleInfo
* info
= static_cast<LocaleInfo
*>(
29 extension
->GetManifestData(keys::kDefaultLocale
));
30 return info
? info
->default_locale
: base::EmptyString();
33 DefaultLocaleHandler::DefaultLocaleHandler() {
36 DefaultLocaleHandler::~DefaultLocaleHandler() {
39 bool DefaultLocaleHandler::Parse(Extension
* extension
, base::string16
* error
) {
40 scoped_ptr
<LocaleInfo
> info(new LocaleInfo
);
41 if (!extension
->manifest()->GetString(keys::kDefaultLocale
,
42 &info
->default_locale
) ||
43 !l10n_util::IsValidLocaleSyntax(info
->default_locale
)) {
44 *error
= base::ASCIIToUTF16(manifest_errors::kInvalidDefaultLocale
);
47 extension
->SetManifestData(keys::kDefaultLocale
, info
.release());
51 bool DefaultLocaleHandler::Validate(
52 const Extension
* extension
,
54 std::vector
<InstallWarning
>* warnings
) const {
55 // default_locale and _locales have to be both present or both missing.
56 const base::FilePath path
= extension
->path().Append(kLocaleFolder
);
57 bool path_exists
= base::PathExists(path
);
58 std::string default_locale
=
59 extensions::LocaleInfo::GetDefaultLocale(extension
);
61 // If both default locale and _locales folder are empty, skip verification.
62 if (default_locale
.empty() && !path_exists
)
65 if (default_locale
.empty() && path_exists
) {
66 *error
= l10n_util::GetStringUTF8(
67 IDS_EXTENSION_LOCALES_NO_DEFAULT_LOCALE_SPECIFIED
);
69 } else if (!default_locale
.empty() && !path_exists
) {
70 *error
= errors::kLocalesTreeMissing
;
74 // Treat all folders under _locales as valid locales.
75 base::FileEnumerator
locales(path
, false, base::FileEnumerator::DIRECTORIES
);
77 std::set
<std::string
> all_locales
;
78 extension_l10n_util::GetAllLocales(&all_locales
);
79 const base::FilePath default_locale_path
= path
.AppendASCII(default_locale
);
80 bool has_default_locale_message_file
= false;
82 base::FilePath locale_path
;
83 while (!(locale_path
= locales
.Next()).empty()) {
84 if (extension_l10n_util::ShouldSkipValidation(path
, locale_path
,
88 base::FilePath messages_path
= locale_path
.Append(kMessagesFilename
);
90 if (!base::PathExists(messages_path
)) {
91 *error
= base::StringPrintf(
92 "%s %s", errors::kLocalesMessagesFileMissing
,
93 base::UTF16ToUTF8(messages_path
.LossyDisplayName()).c_str());
97 if (locale_path
== default_locale_path
)
98 has_default_locale_message_file
= true;
101 // Only message file for default locale has to exist.
102 if (!has_default_locale_message_file
) {
103 *error
= errors::kLocalesNoDefaultMessages
;
110 bool DefaultLocaleHandler::AlwaysValidateForType(Manifest::Type type
) const {
111 // Required to validate _locales directory; see Validate.
115 const std::vector
<std::string
> DefaultLocaleHandler::Keys() const {
116 return SingleKey(keys::kDefaultLocale
);
119 } // namespace extensions