Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / modules / serviceworkers / CacheStorage.cpp
1 // Copyright 2014 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 "config.h"
6 #include "modules/serviceworkers/CacheStorage.h"
7
8 #include "bindings/core/v8/ScriptPromiseResolver.h"
9 #include "bindings/core/v8/ScriptState.h"
10 #include "core/dom/DOMException.h"
11 #include "modules/serviceworkers/Cache.h"
12 #include "public/platform/WebServiceWorkerCacheError.h"
13 #include "public/platform/WebServiceWorkerCacheStorage.h"
14
15 namespace blink {
16
17 namespace {
18
19 PassRefPtrWillBeRawPtr<DOMException> createNoImplementationException()
20 {
21     return DOMException::create(NotSupportedError, "No CacheStorage implementation provided.");
22 }
23
24 }
25
26 // FIXME: Consider using CallbackPromiseAdapter.
27 class CacheStorage::Callbacks final : public WebServiceWorkerCacheStorage::CacheStorageCallbacks {
28     WTF_MAKE_NONCOPYABLE(Callbacks);
29 public:
30     explicit Callbacks(PassRefPtr<ScriptPromiseResolver> resolver)
31         : m_resolver(resolver) { }
32     virtual ~Callbacks() { }
33
34     virtual void onSuccess() override
35     {
36         m_resolver->resolve(true);
37         m_resolver.clear();
38     }
39
40     virtual void onError(WebServiceWorkerCacheError* reason) override
41     {
42         if (*reason == WebServiceWorkerCacheErrorNotFound)
43             m_resolver->resolve(false);
44         else
45             m_resolver->reject(Cache::domExceptionForCacheError(*reason));
46         m_resolver.clear();
47     }
48
49 private:
50     RefPtr<ScriptPromiseResolver> m_resolver;
51 };
52
53 // FIXME: Consider using CallbackPromiseAdapter.
54 class CacheStorage::WithCacheCallbacks final : public WebServiceWorkerCacheStorage::CacheStorageWithCacheCallbacks {
55     WTF_MAKE_NONCOPYABLE(WithCacheCallbacks);
56 public:
57     WithCacheCallbacks(const String& cacheName, CacheStorage* cacheStorage, PassRefPtr<ScriptPromiseResolver> resolver)
58         : m_cacheName(cacheName), m_cacheStorage(cacheStorage), m_resolver(resolver) { }
59     virtual ~WithCacheCallbacks() { }
60
61     virtual void onSuccess(WebServiceWorkerCache* webCache) override
62     {
63         // FIXME: Remove this once content's WebServiceWorkerCache implementation has landed.
64         if (!webCache) {
65             m_resolver->reject("not implemented");
66             return;
67         }
68         Cache* cache = Cache::create(webCache);
69         m_cacheStorage->m_nameToCacheMap.set(m_cacheName, cache);
70         m_resolver->resolve(cache);
71         m_resolver.clear();
72     }
73
74     virtual void onError(WebServiceWorkerCacheError* reason) override
75     {
76         if (*reason == WebServiceWorkerCacheErrorNotFound)
77             m_resolver->resolve();
78         else
79             m_resolver->reject(Cache::domExceptionForCacheError(*reason));
80         m_resolver.clear();
81     }
82
83 private:
84     String m_cacheName;
85     Persistent<CacheStorage> m_cacheStorage;
86     RefPtr<ScriptPromiseResolver> m_resolver;
87 };
88
89 // FIXME: Consider using CallbackPromiseAdapter.
90 class CacheStorage::DeleteCallbacks final : public WebServiceWorkerCacheStorage::CacheStorageCallbacks {
91     WTF_MAKE_NONCOPYABLE(DeleteCallbacks);
92 public:
93     DeleteCallbacks(const String& cacheName, CacheStorage* cacheStorage, PassRefPtr<ScriptPromiseResolver> resolver)
94         : m_cacheName(cacheName), m_cacheStorage(cacheStorage), m_resolver(resolver) { }
95     virtual ~DeleteCallbacks() { }
96
97     virtual void onSuccess() override
98     {
99         m_cacheStorage->m_nameToCacheMap.remove(m_cacheName);
100         m_resolver->resolve(true);
101         m_resolver.clear();
102     }
103
104     virtual void onError(WebServiceWorkerCacheError* reason) override
105     {
106         if (*reason == WebServiceWorkerCacheErrorNotFound)
107             m_resolver->resolve(false);
108         else
109             m_resolver->reject(Cache::domExceptionForCacheError(*reason));
110         m_resolver.clear();
111     }
112
113 private:
114     String m_cacheName;
115     Persistent<CacheStorage> m_cacheStorage;
116     RefPtr<ScriptPromiseResolver> m_resolver;
117 };
118
119 // FIXME: Consider using CallbackPromiseAdapter.
120 class CacheStorage::KeysCallbacks final : public WebServiceWorkerCacheStorage::CacheStorageKeysCallbacks {
121     WTF_MAKE_NONCOPYABLE(KeysCallbacks);
122 public:
123     explicit KeysCallbacks(PassRefPtr<ScriptPromiseResolver> resolver)
124         : m_resolver(resolver) { }
125     virtual ~KeysCallbacks() { }
126
127     virtual void onSuccess(WebVector<WebString>* keys) override
128     {
129         Vector<String> wtfKeys;
130         for (size_t i = 0; i < keys->size(); ++i)
131             wtfKeys.append((*keys)[i]);
132         m_resolver->resolve(wtfKeys);
133         m_resolver.clear();
134     }
135
136     virtual void onError(WebServiceWorkerCacheError* reason) override
137     {
138         m_resolver->reject(Cache::domExceptionForCacheError(*reason));
139         m_resolver.clear();
140     }
141
142 private:
143     RefPtr<ScriptPromiseResolver> m_resolver;
144 };
145
146 CacheStorage* CacheStorage::create(WebServiceWorkerCacheStorage* webCacheStorage)
147 {
148     return new CacheStorage(webCacheStorage);
149 }
150
151 ScriptPromise CacheStorage::open(ScriptState* scriptState, const String& cacheName)
152 {
153     RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
154     const ScriptPromise promise = resolver->promise();
155
156     if (m_nameToCacheMap.contains(cacheName)) {
157         Cache* cache = m_nameToCacheMap.find(cacheName)->value;
158         resolver->resolve(cache);
159         return promise;
160     }
161
162     if (m_webCacheStorage)
163         m_webCacheStorage->dispatchOpen(new WithCacheCallbacks(cacheName, this, resolver), cacheName);
164     else
165         resolver->reject(createNoImplementationException());
166
167     return promise;
168 }
169
170 ScriptPromise CacheStorage::has(ScriptState* scriptState, const String& cacheName)
171 {
172     RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
173     const ScriptPromise promise = resolver->promise();
174
175     if (m_nameToCacheMap.contains(cacheName)) {
176         resolver->resolve(true);
177         return promise;
178     }
179
180     if (m_webCacheStorage)
181         m_webCacheStorage->dispatchHas(new Callbacks(resolver), cacheName);
182     else
183         resolver->reject(createNoImplementationException());
184
185     return promise;
186 }
187
188 ScriptPromise CacheStorage::deleteFunction(ScriptState* scriptState, const String& cacheName)
189 {
190     RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
191     const ScriptPromise promise = resolver->promise();
192
193     if (m_webCacheStorage)
194         m_webCacheStorage->dispatchDelete(new DeleteCallbacks(cacheName, this, resolver), cacheName);
195     else
196         resolver->reject(createNoImplementationException());
197
198     return promise;
199 }
200
201 ScriptPromise CacheStorage::keys(ScriptState* scriptState)
202 {
203     RefPtr<ScriptPromiseResolver> resolver = ScriptPromiseResolver::create(scriptState);
204     const ScriptPromise promise = resolver->promise();
205
206     if (m_webCacheStorage)
207         m_webCacheStorage->dispatchKeys(new KeysCallbacks(resolver));
208     else
209         resolver->reject(createNoImplementationException());
210
211     return promise;
212 }
213
214 void CacheStorage::trace(Visitor* visitor)
215 {
216     visitor->trace(m_nameToCacheMap);
217 }
218
219 CacheStorage::CacheStorage(WebServiceWorkerCacheStorage* webCacheStorage)
220     : m_webCacheStorage(webCacheStorage)
221 {
222 }
223
224 } // namespace blink