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.
5 #ifndef WEBKIT_BROWSER_APPCACHE_APPCACHE_H_
6 #define WEBKIT_BROWSER_APPCACHE_APPCACHE_H_
12 #include "base/gtest_prod_util.h"
13 #include "base/memory/ref_counted.h"
14 #include "base/time/time.h"
16 #include "webkit/browser/appcache/appcache_database.h"
17 #include "webkit/browser/appcache/appcache_entry.h"
18 #include "webkit/browser/appcache/manifest_parser.h"
19 #include "webkit/browser/webkit_storage_browser_export.h"
26 FORWARD_DECLARE_TEST(AppCacheTest
, InitializeWithManifest
);
27 FORWARD_DECLARE_TEST(AppCacheTest
, ToFromDatabaseRecords
);
29 class AppCacheStorageImplTest
;
30 class AppCacheUpdateJobTest
;
35 class AppCacheExecutableHandler
;
38 class AppCacheStorage
;
40 // Set of cached resources for an application. A cache exists as long as a
41 // host is associated with it, the cache is in an appcache group or the
42 // cache is being created during an appcache upate.
43 class WEBKIT_STORAGE_BROWSER_EXPORT AppCache
44 : public base::RefCounted
<AppCache
> {
46 typedef std::map
<GURL
, AppCacheEntry
> EntryMap
;
47 typedef std::set
<AppCacheHost
*> AppCacheHosts
;
49 AppCache(AppCacheStorage
* storage
, int64 cache_id
);
51 int64
cache_id() const { return cache_id_
; }
53 AppCacheGroup
* owning_group() const { return owning_group_
.get(); }
55 bool is_complete() const { return is_complete_
; }
56 void set_complete(bool value
) { is_complete_
= value
; }
58 // Adds a new entry. Entry must not already be in cache.
59 void AddEntry(const GURL
& url
, const AppCacheEntry
& entry
);
61 // Adds a new entry or modifies an existing entry by merging the types
62 // of the new entry with the existing entry. Returns true if a new entry
63 // is added, false if the flags are merged into an existing entry.
64 bool AddOrModifyEntry(const GURL
& url
, const AppCacheEntry
& entry
);
66 // Removes an entry from the EntryMap, the URL must be in the set.
67 void RemoveEntry(const GURL
& url
);
69 // Do not store or delete the returned ptr, they're owned by 'this'.
70 AppCacheEntry
* GetEntry(const GURL
& url
);
71 const AppCacheEntry
* GetEntryWithResponseId(int64 response_id
) {
72 return GetEntryAndUrlWithResponseId(response_id
, NULL
);
74 const AppCacheEntry
* GetEntryAndUrlWithResponseId(
75 int64 response_id
, GURL
* optional_url
);
76 const EntryMap
& entries() const { return entries_
; }
78 // The AppCache owns the collection of executable handlers that have
79 // been started for this instance. The getter looks up an existing
80 // handler returning null if not found, the GetOrCreate method will
81 // cons one up if not found.
82 // Do not store the returned ptrs, they're owned by 'this'.
83 AppCacheExecutableHandler
* GetExecutableHandler(int64 response_id
);
84 AppCacheExecutableHandler
* GetOrCreateExecutableHandler(
85 int64 response_id
, net::IOBuffer
* handler_source
);
87 // Returns the URL of the resource used as entry for 'namespace_url'.
88 GURL
GetFallbackEntryUrl(const GURL
& namespace_url
) const {
89 return GetNamespaceEntryUrl(fallback_namespaces_
, namespace_url
);
91 GURL
GetInterceptEntryUrl(const GURL
& namespace_url
) const {
92 return GetNamespaceEntryUrl(intercept_namespaces_
, namespace_url
);
95 AppCacheHosts
& associated_hosts() { return associated_hosts_
; }
97 bool IsNewerThan(AppCache
* cache
) const {
98 // TODO(michaeln): revisit, the system clock can be set
99 // back in time which would confuse this logic.
100 if (update_time_
> cache
->update_time_
)
103 // Tie breaker. Newer caches have a larger cache ID.
104 if (update_time_
== cache
->update_time_
)
105 return cache_id_
> cache
->cache_id_
;
110 base::Time
update_time() const { return update_time_
; }
112 int64
cache_size() const { return cache_size_
; }
114 void set_update_time(base::Time ticks
) { update_time_
= ticks
; }
116 // Initializes the cache with information in the manifest.
117 // Do not use the manifest after this call.
118 void InitializeWithManifest(Manifest
* manifest
);
120 // Initializes the cache with the information in the database records.
121 void InitializeWithDatabaseRecords(
122 const AppCacheDatabase::CacheRecord
& cache_record
,
123 const std::vector
<AppCacheDatabase::EntryRecord
>& entries
,
124 const std::vector
<AppCacheDatabase::NamespaceRecord
>& intercepts
,
125 const std::vector
<AppCacheDatabase::NamespaceRecord
>& fallbacks
,
126 const std::vector
<AppCacheDatabase::OnlineWhiteListRecord
>& whitelists
);
128 // Returns the database records to be stored in the AppCacheDatabase
129 // to represent this cache.
130 void ToDatabaseRecords(
131 const AppCacheGroup
* group
,
132 AppCacheDatabase::CacheRecord
* cache_record
,
133 std::vector
<AppCacheDatabase::EntryRecord
>* entries
,
134 std::vector
<AppCacheDatabase::NamespaceRecord
>* intercepts
,
135 std::vector
<AppCacheDatabase::NamespaceRecord
>* fallbacks
,
136 std::vector
<AppCacheDatabase::OnlineWhiteListRecord
>* whitelists
);
138 bool FindResponseForRequest(const GURL
& url
,
139 AppCacheEntry
* found_entry
, GURL
* found_intercept_namespace
,
140 AppCacheEntry
* found_fallback_entry
, GURL
* found_fallback_namespace
,
141 bool* found_network_namespace
);
143 // Populates the 'infos' vector with an element per entry in the appcache.
144 void ToResourceInfoVector(AppCacheResourceInfoVector
* infos
) const;
146 static const Namespace
* FindNamespace(
147 const NamespaceVector
& namespaces
,
151 friend class AppCacheGroup
;
152 friend class AppCacheHost
;
153 friend class content::AppCacheTest
;
154 friend class content::AppCacheStorageImplTest
;
155 friend class content::AppCacheUpdateJobTest
;
156 friend class base::RefCounted
<AppCache
>;
160 // Use AppCacheGroup::Add/RemoveCache() to manipulate owning group.
161 void set_owning_group(AppCacheGroup
* group
) { owning_group_
= group
; }
163 // FindResponseForRequest helpers
164 const Namespace
* FindInterceptNamespace(const GURL
& url
) {
165 return FindNamespace(intercept_namespaces_
, url
);
167 const Namespace
* FindFallbackNamespace(const GURL
& url
) {
168 return FindNamespace(fallback_namespaces_
, url
);
170 bool IsInNetworkNamespace(const GURL
& url
) {
171 return FindNamespace(online_whitelist_namespaces_
, url
) != NULL
;
174 GURL
GetNamespaceEntryUrl(const NamespaceVector
& namespaces
,
175 const GURL
& namespace_url
) const;
177 // Use AppCacheHost::Associate*Cache() to manipulate host association.
178 void AssociateHost(AppCacheHost
* host
) {
179 associated_hosts_
.insert(host
);
181 void UnassociateHost(AppCacheHost
* host
);
183 const int64 cache_id_
;
184 scoped_refptr
<AppCacheGroup
> owning_group_
;
185 AppCacheHosts associated_hosts_
;
187 EntryMap entries_
; // contains entries of all types
189 NamespaceVector intercept_namespaces_
;
190 NamespaceVector fallback_namespaces_
;
191 NamespaceVector online_whitelist_namespaces_
;
192 bool online_whitelist_all_
;
196 // when this cache was last updated
197 base::Time update_time_
;
201 typedef std::map
<int64
, AppCacheExecutableHandler
*> HandlerMap
;
202 HandlerMap executable_handlers_
;
204 // to notify storage when cache is deleted
205 AppCacheStorage
* storage_
;
207 FRIEND_TEST_ALL_PREFIXES(content::AppCacheTest
, InitializeWithManifest
);
208 FRIEND_TEST_ALL_PREFIXES(content::AppCacheTest
, ToFromDatabaseRecords
);
209 DISALLOW_COPY_AND_ASSIGN(AppCache
);
212 } // namespace appcache
214 #endif // WEBKIT_BROWSER_APPCACHE_APPCACHE_H_