- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / content_settings / content_settings_origin_identifier_value_map.cc
1 // Copyright (c) 2012 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 "chrome/browser/content_settings/content_settings_origin_identifier_value_map.h"
6
7 #include "base/compiler_specific.h"
8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/synchronization/lock.h"
11 #include "base/values.h"
12 #include "chrome/browser/content_settings/content_settings_rule.h"
13 #include "chrome/browser/content_settings/content_settings_utils.h"
14 #include "chrome/common/content_settings_types.h"
15 #include "url/gurl.h"
16
17 namespace content_settings {
18
19 namespace {
20
21 // This iterator is used for iterating the rules for |content_type| and
22 // |resource_identifier| in the precedence order of the rules.
23 class RuleIteratorImpl : public RuleIterator {
24  public:
25   // |RuleIteratorImpl| takes the ownership of |auto_lock|.
26   RuleIteratorImpl(
27       const OriginIdentifierValueMap::Rules::const_iterator& current_rule,
28       const OriginIdentifierValueMap::Rules::const_iterator& rule_end,
29       base::AutoLock* auto_lock)
30       : current_rule_(current_rule),
31         rule_end_(rule_end),
32         auto_lock_(auto_lock) {
33   }
34   virtual ~RuleIteratorImpl() {}
35
36   virtual bool HasNext() const OVERRIDE {
37     return (current_rule_ != rule_end_);
38   }
39
40   virtual Rule Next() OVERRIDE {
41     DCHECK(current_rule_ != rule_end_);
42     DCHECK(current_rule_->second.get());
43     Rule to_return(current_rule_->first.primary_pattern,
44                    current_rule_->first.secondary_pattern,
45                    current_rule_->second.get()->DeepCopy());
46     ++current_rule_;
47     return to_return;
48   }
49
50  private:
51   OriginIdentifierValueMap::Rules::const_iterator current_rule_;
52   OriginIdentifierValueMap::Rules::const_iterator rule_end_;
53   scoped_ptr<base::AutoLock> auto_lock_;
54 };
55
56 }  // namespace
57
58 OriginIdentifierValueMap::EntryMapKey::EntryMapKey(
59     ContentSettingsType content_type,
60     const ResourceIdentifier& resource_identifier)
61     : content_type(content_type),
62       resource_identifier(resource_identifier) {
63 }
64
65 bool OriginIdentifierValueMap::EntryMapKey::operator<(
66     const OriginIdentifierValueMap::EntryMapKey& other) const {
67   if (content_type != other.content_type)
68     return content_type < other.content_type;
69   return (resource_identifier < other.resource_identifier);
70 }
71
72 OriginIdentifierValueMap::PatternPair::PatternPair(
73     const ContentSettingsPattern& primary_pattern,
74     const ContentSettingsPattern& secondary_pattern)
75     : primary_pattern(primary_pattern),
76       secondary_pattern(secondary_pattern) {
77 }
78
79 bool OriginIdentifierValueMap::PatternPair::operator<(
80     const OriginIdentifierValueMap::PatternPair& other) const {
81   // Note that this operator is the other way around than
82   // |ContentSettingsPattern::operator<|. It sorts patterns with higher
83   // precedence first.
84   if (primary_pattern > other.primary_pattern)
85     return true;
86   else if (other.primary_pattern > primary_pattern)
87     return false;
88   return (secondary_pattern > other.secondary_pattern);
89 }
90
91 RuleIterator* OriginIdentifierValueMap::GetRuleIterator(
92     ContentSettingsType content_type,
93     const ResourceIdentifier& resource_identifier,
94     base::Lock* lock) const {
95   EntryMapKey key(content_type, resource_identifier);
96   // We access |entries_| here, so we need to lock |lock_| first. The lock must
97   // be passed to the |RuleIteratorImpl| in a locked state, so that nobody can
98   // access |entries_| after |find()| but before the |RuleIteratorImpl| is
99   // created.
100   scoped_ptr<base::AutoLock> auto_lock;
101   if (lock)
102     auto_lock.reset(new base::AutoLock(*lock));
103   EntryMap::const_iterator it = entries_.find(key);
104   if (it == entries_.end())
105     return new EmptyRuleIterator();
106   return new RuleIteratorImpl(it->second.begin(),
107                               it->second.end(),
108                               auto_lock.release());
109 }
110
111 size_t OriginIdentifierValueMap::size() const {
112   size_t size = 0;
113   EntryMap::const_iterator it;
114   for (it = entries_.begin(); it != entries_.end(); ++it)
115     size += it->second.size();
116   return size;
117 }
118
119 OriginIdentifierValueMap::OriginIdentifierValueMap() {}
120
121 OriginIdentifierValueMap::~OriginIdentifierValueMap() {}
122
123 Value* OriginIdentifierValueMap::GetValue(
124     const GURL& primary_url,
125     const GURL& secondary_url,
126     ContentSettingsType content_type,
127     const ResourceIdentifier& resource_identifier) const {
128   EntryMapKey key(content_type, resource_identifier);
129   EntryMap::const_iterator it = entries_.find(key);
130   if (it == entries_.end())
131       return NULL;
132
133   // Iterate the entries in until a match is found. Since the rules are stored
134   // in the order of decreasing precedence, the most specific match is found
135   // first.
136   Rules::const_iterator entry;
137   for (entry = it->second.begin(); entry != it->second.end(); ++entry) {
138     if (entry->first.primary_pattern.Matches(primary_url) &&
139         entry->first.secondary_pattern.Matches(secondary_url)) {
140       return entry->second.get();
141     }
142   }
143   return NULL;
144 }
145
146 void OriginIdentifierValueMap::SetValue(
147     const ContentSettingsPattern& primary_pattern,
148     const ContentSettingsPattern& secondary_pattern,
149     ContentSettingsType content_type,
150     const ResourceIdentifier& resource_identifier,
151     Value* value) {
152   DCHECK(primary_pattern.IsValid());
153   DCHECK(secondary_pattern.IsValid());
154   DCHECK(value);
155   EntryMapKey key(content_type, resource_identifier);
156   PatternPair patterns(primary_pattern, secondary_pattern);
157   // This will create the entry and the linked_ptr if needed.
158   entries_[key][patterns].reset(value);
159 }
160
161 void OriginIdentifierValueMap::DeleteValue(
162       const ContentSettingsPattern& primary_pattern,
163       const ContentSettingsPattern& secondary_pattern,
164       ContentSettingsType content_type,
165       const ResourceIdentifier& resource_identifier) {
166   EntryMapKey key(content_type, resource_identifier);
167   PatternPair patterns(primary_pattern, secondary_pattern);
168   entries_[key].erase(patterns);
169   if (entries_[key].empty()) {
170     entries_.erase(key);
171   }
172 }
173
174 void OriginIdentifierValueMap::DeleteValues(
175       ContentSettingsType content_type,
176       const ResourceIdentifier& resource_identifier) {
177   EntryMapKey key(content_type, resource_identifier);
178   entries_.erase(key);
179 }
180
181 void OriginIdentifierValueMap::clear() {
182   // Delete all owned value objects.
183   entries_.clear();
184 }
185
186 }  // namespace content_settings