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"
27 class AppCacheExecutableHandler
;
30 class AppCacheStorage
;
32 // Set of cached resources for an application. A cache exists as long as a
33 // host is associated with it, the cache is in an appcache group or the
34 // cache is being created during an appcache upate.
35 class WEBKIT_STORAGE_BROWSER_EXPORT AppCache
36 : public base::RefCounted
<AppCache
> {
38 typedef std::map
<GURL
, AppCacheEntry
> EntryMap
;
39 typedef std::set
<AppCacheHost
*> AppCacheHosts
;
41 AppCache(AppCacheStorage
* storage
, int64 cache_id
);
43 int64
cache_id() const { return cache_id_
; }
45 AppCacheGroup
* owning_group() const { return owning_group_
.get(); }
47 bool is_complete() const { return is_complete_
; }
48 void set_complete(bool value
) { is_complete_
= value
; }
50 // Adds a new entry. Entry must not already be in cache.
51 void AddEntry(const GURL
& url
, const AppCacheEntry
& entry
);
53 // Adds a new entry or modifies an existing entry by merging the types
54 // of the new entry with the existing entry. Returns true if a new entry
55 // is added, false if the flags are merged into an existing entry.
56 bool AddOrModifyEntry(const GURL
& url
, const AppCacheEntry
& entry
);
58 // Removes an entry from the EntryMap, the URL must be in the set.
59 void RemoveEntry(const GURL
& url
);
61 // Do not store or delete the returned ptr, they're owned by 'this'.
62 AppCacheEntry
* GetEntry(const GURL
& url
);
63 const AppCacheEntry
* GetEntryWithResponseId(int64 response_id
) {
64 return GetEntryAndUrlWithResponseId(response_id
, NULL
);
66 const AppCacheEntry
* GetEntryAndUrlWithResponseId(
67 int64 response_id
, GURL
* optional_url
);
68 const EntryMap
& entries() const { return entries_
; }
70 // The AppCache owns the collection of executable handlers that have
71 // been started for this instance. The getter looks up an existing
72 // handler returning null if not found, the GetOrCreate method will
73 // cons one up if not found.
74 // Do not store the returned ptrs, they're owned by 'this'.
75 AppCacheExecutableHandler
* GetExecutableHandler(int64 response_id
);
76 AppCacheExecutableHandler
* GetOrCreateExecutableHandler(
77 int64 response_id
, net::IOBuffer
* handler_source
);
79 // Returns the URL of the resource used as entry for 'namespace_url'.
80 GURL
GetFallbackEntryUrl(const GURL
& namespace_url
) const {
81 return GetNamespaceEntryUrl(fallback_namespaces_
, namespace_url
);
83 GURL
GetInterceptEntryUrl(const GURL
& namespace_url
) const {
84 return GetNamespaceEntryUrl(intercept_namespaces_
, namespace_url
);
87 AppCacheHosts
& associated_hosts() { return associated_hosts_
; }
89 bool IsNewerThan(AppCache
* cache
) const {
90 // TODO(michaeln): revisit, the system clock can be set
91 // back in time which would confuse this logic.
92 if (update_time_
> cache
->update_time_
)
95 // Tie breaker. Newer caches have a larger cache ID.
96 if (update_time_
== cache
->update_time_
)
97 return cache_id_
> cache
->cache_id_
;
102 base::Time
update_time() const { return update_time_
; }
104 int64
cache_size() const { return cache_size_
; }
106 void set_update_time(base::Time ticks
) { update_time_
= ticks
; }
108 // Initializes the cache with information in the manifest.
109 // Do not use the manifest after this call.
110 void InitializeWithManifest(Manifest
* manifest
);
112 // Initializes the cache with the information in the database records.
113 void InitializeWithDatabaseRecords(
114 const AppCacheDatabase::CacheRecord
& cache_record
,
115 const std::vector
<AppCacheDatabase::EntryRecord
>& entries
,
116 const std::vector
<AppCacheDatabase::NamespaceRecord
>& intercepts
,
117 const std::vector
<AppCacheDatabase::NamespaceRecord
>& fallbacks
,
118 const std::vector
<AppCacheDatabase::OnlineWhiteListRecord
>& whitelists
);
120 // Returns the database records to be stored in the AppCacheDatabase
121 // to represent this cache.
122 void ToDatabaseRecords(
123 const AppCacheGroup
* group
,
124 AppCacheDatabase::CacheRecord
* cache_record
,
125 std::vector
<AppCacheDatabase::EntryRecord
>* entries
,
126 std::vector
<AppCacheDatabase::NamespaceRecord
>* intercepts
,
127 std::vector
<AppCacheDatabase::NamespaceRecord
>* fallbacks
,
128 std::vector
<AppCacheDatabase::OnlineWhiteListRecord
>* whitelists
);
130 bool FindResponseForRequest(const GURL
& url
,
131 AppCacheEntry
* found_entry
, GURL
* found_intercept_namespace
,
132 AppCacheEntry
* found_fallback_entry
, GURL
* found_fallback_namespace
,
133 bool* found_network_namespace
);
135 // Populates the 'infos' vector with an element per entry in the appcache.
136 void ToResourceInfoVector(AppCacheResourceInfoVector
* infos
) const;
138 static const Namespace
* FindNamespace(
139 const NamespaceVector
& namespaces
,
143 friend class AppCacheGroup
;
144 friend class AppCacheHost
;
145 friend class AppCacheStorageImplTest
;
146 friend class AppCacheUpdateJobTest
;
147 friend class base::RefCounted
<AppCache
>;
151 // Use AppCacheGroup::Add/RemoveCache() to manipulate owning group.
152 void set_owning_group(AppCacheGroup
* group
) { owning_group_
= group
; }
154 // FindResponseForRequest helpers
155 const Namespace
* FindInterceptNamespace(const GURL
& url
) {
156 return FindNamespace(intercept_namespaces_
, url
);
158 const Namespace
* FindFallbackNamespace(const GURL
& url
) {
159 return FindNamespace(fallback_namespaces_
, url
);
161 bool IsInNetworkNamespace(const GURL
& url
) {
162 return FindNamespace(online_whitelist_namespaces_
, url
) != NULL
;
165 GURL
GetNamespaceEntryUrl(const NamespaceVector
& namespaces
,
166 const GURL
& namespace_url
) const;
168 // Use AppCacheHost::Associate*Cache() to manipulate host association.
169 void AssociateHost(AppCacheHost
* host
) {
170 associated_hosts_
.insert(host
);
172 void UnassociateHost(AppCacheHost
* host
);
174 const int64 cache_id_
;
175 scoped_refptr
<AppCacheGroup
> owning_group_
;
176 AppCacheHosts associated_hosts_
;
178 EntryMap entries_
; // contains entries of all types
180 NamespaceVector intercept_namespaces_
;
181 NamespaceVector fallback_namespaces_
;
182 NamespaceVector online_whitelist_namespaces_
;
183 bool online_whitelist_all_
;
187 // when this cache was last updated
188 base::Time update_time_
;
192 typedef std::map
<int64
, AppCacheExecutableHandler
*> HandlerMap
;
193 HandlerMap executable_handlers_
;
195 // to notify storage when cache is deleted
196 AppCacheStorage
* storage_
;
198 FRIEND_TEST_ALL_PREFIXES(AppCacheTest
, InitializeWithManifest
);
199 FRIEND_TEST_ALL_PREFIXES(AppCacheTest
, ToFromDatabaseRecords
);
200 DISALLOW_COPY_AND_ASSIGN(AppCache
);
203 } // namespace appcache
205 #endif // WEBKIT_BROWSER_APPCACHE_APPCACHE_H_