1 // Copyright 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.
4
5 #include "components/policy/core/browser/policy_error_map.h"
6
7 #include <utility>
8
9 #include "base/strings/string_number_conversions.h"
10 #include "base/strings/string_util.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "grit/components_strings.h"
13 #include "ui/base/l10n/l10n_util.h"
14 #include "ui/base/resource/resource_bundle.h"
15
16 namespace policy {
17
18 class PolicyErrorMap::PendingError {
19 public:
PendingError(const std::string & policy_name)20 explicit PendingError(const std::string& policy_name)
21 : policy_name_(policy_name) {}
~PendingError()22 virtual ~PendingError() {}
23
policy_name() const24 const std::string& policy_name() const { return policy_name_; }
25
26 virtual base::string16 GetMessage() const = 0;
27
28 private:
29 std::string policy_name_;
30
31 DISALLOW_COPY_AND_ASSIGN(PendingError);
32 };
33
34 namespace {
35
36 class SimplePendingError : public PolicyErrorMap::PendingError {
37 public:
SimplePendingError(const std::string & policy_name,int message_id,const std::string & replacement)38 SimplePendingError(const std::string& policy_name,
39 int message_id,
40 const std::string& replacement)
41 : PendingError(policy_name),
42 message_id_(message_id),
43 replacement_(replacement) {}
~SimplePendingError()44 virtual ~SimplePendingError() {}
45
GetMessage() const46 virtual base::string16 GetMessage() const OVERRIDE {
47 if (message_id_ >= 0) {
48 if (replacement_.empty())
49 return l10n_util::GetStringUTF16(message_id_);
50 return l10n_util::GetStringFUTF16(message_id_,
51 base::ASCIIToUTF16(replacement_));
52 }
53 return base::ASCIIToUTF16(replacement_);
54 }
55
56 private:
57 int message_id_;
58 std::string replacement_;
59
60 DISALLOW_COPY_AND_ASSIGN(SimplePendingError);
61 };
62
63 class DictSubkeyPendingError : public SimplePendingError {
64 public:
DictSubkeyPendingError(const std::string & policy_name,const std::string & subkey,int message_id,const std::string & replacement)65 DictSubkeyPendingError(const std::string& policy_name,
66 const std::string& subkey,
67 int message_id,
68 const std::string& replacement)
69 : SimplePendingError(policy_name, message_id, replacement),
70 subkey_(subkey) {}
~DictSubkeyPendingError()71 virtual ~DictSubkeyPendingError() {}
72
GetMessage() const73 virtual base::string16 GetMessage() const OVERRIDE {
74 return l10n_util::GetStringFUTF16(IDS_POLICY_SUBKEY_ERROR,
75 base::ASCIIToUTF16(subkey_),
76 SimplePendingError::GetMessage());
77 }
78
79 private:
80 std::string subkey_;
81
82 DISALLOW_COPY_AND_ASSIGN(DictSubkeyPendingError);
83 };
84
85 class ListItemPendingError : public SimplePendingError {
86 public:
ListItemPendingError(const std::string & policy_name,int index,int message_id,const std::string & replacement)87 ListItemPendingError(const std::string& policy_name,
88 int index,
89 int message_id,
90 const std::string& replacement)
91 : SimplePendingError(policy_name, message_id, replacement),
92 index_(index) {}
~ListItemPendingError()93 virtual ~ListItemPendingError() {}
94
GetMessage() const95 virtual base::string16 GetMessage() const OVERRIDE {
96 return l10n_util::GetStringFUTF16(IDS_POLICY_LIST_ENTRY_ERROR,
97 base::IntToString16(index_),
98 SimplePendingError::GetMessage());
99 }
100
101 private:
102 int index_;
103
104 DISALLOW_COPY_AND_ASSIGN(ListItemPendingError);
105 };
106
107 class SchemaValidatingPendingError : public SimplePendingError {
108 public:
SchemaValidatingPendingError(const std::string & policy_name,const std::string & error_path,const std::string & replacement)109 SchemaValidatingPendingError(const std::string& policy_name,
110 const std::string& error_path,
111 const std::string& replacement)
112 : SimplePendingError(policy_name, -1, replacement),
113 error_path_(error_path) {};
~SchemaValidatingPendingError()114 virtual ~SchemaValidatingPendingError() {}
115
GetMessage() const116 virtual base::string16 GetMessage() const OVERRIDE {
117 return l10n_util::GetStringFUTF16(IDS_POLICY_SCHEMA_VALIDATION_ERROR,
118 base::ASCIIToUTF16(error_path_),
119 SimplePendingError::GetMessage());
120 }
121
122 private:
123 std::string error_path_;
124
125 DISALLOW_COPY_AND_ASSIGN(SchemaValidatingPendingError);
126 };
127
128 } // namespace
129
PolicyErrorMap()130 PolicyErrorMap::PolicyErrorMap() {
131 }
132
~PolicyErrorMap()133 PolicyErrorMap::~PolicyErrorMap() {
134 }
135
IsReady() const136 bool PolicyErrorMap::IsReady() const {
137 return ui::ResourceBundle::HasSharedInstance();
138 }
139
AddError(const std::string & policy,int message_id)140 void PolicyErrorMap::AddError(const std::string& policy, int message_id) {
141 AddError(new SimplePendingError(policy, message_id, std::string()));
142 }
143
AddError(const std::string & policy,const std::string & subkey,int message_id)144 void PolicyErrorMap::AddError(const std::string& policy,
145 const std::string& subkey,
146 int message_id) {
147 AddError(
148 new DictSubkeyPendingError(policy, subkey, message_id, std::string()));
149 }
150
AddError(const std::string & policy,int index,int message_id)151 void PolicyErrorMap::AddError(const std::string& policy,
152 int index,
153 int message_id) {
154 AddError(new ListItemPendingError(policy, index, message_id, std::string()));
155 }
156
AddError(const std::string & policy,int message_id,const std::string & replacement)157 void PolicyErrorMap::AddError(const std::string& policy,
158 int message_id,
159 const std::string& replacement) {
160 AddError(new SimplePendingError(policy, message_id, replacement));
161 }
162
AddError(const std::string & policy,const std::string & subkey,int message_id,const std::string & replacement)163 void PolicyErrorMap::AddError(const std::string& policy,
164 const std::string& subkey,
165 int message_id,
166 const std::string& replacement) {
167 AddError(new DictSubkeyPendingError(policy, subkey, message_id, replacement));
168 }
169
AddError(const std::string & policy,int index,int message_id,const std::string & replacement)170 void PolicyErrorMap::AddError(const std::string& policy,
171 int index,
172 int message_id,
173 const std::string& replacement) {
174 AddError(new ListItemPendingError(policy, index, message_id, replacement));
175 }
176
AddError(const std::string & policy,const std::string & error_path,const std::string & message)177 void PolicyErrorMap::AddError(const std::string& policy,
178 const std::string& error_path,
179 const std::string& message) {
180 AddError(new SchemaValidatingPendingError(policy, error_path, message));
181 }
182
GetErrors(const std::string & policy)183 base::string16 PolicyErrorMap::GetErrors(const std::string& policy) {
184 CheckReadyAndConvert();
185 std::pair<const_iterator, const_iterator> range = map_.equal_range(policy);
186 std::vector<base::string16> list;
187 for (const_iterator it = range.first; it != range.second; ++it)
188 list.push_back(it->second);
189 return JoinString(list, '\n');
190 }
191
empty()192 bool PolicyErrorMap::empty() {
193 CheckReadyAndConvert();
194 return map_.empty();
195 }
196
size()197 size_t PolicyErrorMap::size() {
198 CheckReadyAndConvert();
199 return map_.size();
200 }
201
begin()202 PolicyErrorMap::const_iterator PolicyErrorMap::begin() {
203 CheckReadyAndConvert();
204 return map_.begin();
205 }
206
end()207 PolicyErrorMap::const_iterator PolicyErrorMap::end() {
208 CheckReadyAndConvert();
209 return map_.end();
210 }
211
Clear()212 void PolicyErrorMap::Clear() {
213 CheckReadyAndConvert();
214 map_.clear();
215 }
216
AddError(PendingError * error)217 void PolicyErrorMap::AddError(PendingError* error) {
218 if (IsReady()) {
219 Convert(error);
220 delete error;
221 } else {
222 pending_.push_back(error);
223 }
224 }
225
Convert(PendingError * error)226 void PolicyErrorMap::Convert(PendingError* error) {
227 map_.insert(std::make_pair(error->policy_name(), error->GetMessage()));
228 }
229
CheckReadyAndConvert()230 void PolicyErrorMap::CheckReadyAndConvert() {
231 DCHECK(IsReady());
232 for (size_t i = 0; i < pending_.size(); ++i) {
233 Convert(pending_[i]);
234 }
235 pending_.clear();
236 }
237
238 } // namespace policy
239