1 /* 2 * Copyright (C) 2010 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 #include "config.h" 32 #include "modules/filesystem/FileSystemCallbacks.h" 33 34 #include "core/dom/ScriptExecutionContext.h" 35 #include "core/fileapi/FileError.h" 36 #include "core/html/VoidCallback.h" 37 #include "core/platform/AsyncFileSystem.h" 38 #include "core/platform/FileMetadata.h" 39 #include "modules/filesystem/AsyncFileWriter.h" 40 #include "modules/filesystem/DOMFilePath.h" 41 #include "modules/filesystem/DOMFileSystemBase.h" 42 #include "modules/filesystem/DirectoryEntry.h" 43 #include "modules/filesystem/DirectoryReader.h" 44 #include "modules/filesystem/EntriesCallback.h" 45 #include "modules/filesystem/Entry.h" 46 #include "modules/filesystem/EntryCallback.h" 47 #include "modules/filesystem/ErrorCallback.h" 48 #include "modules/filesystem/FileEntry.h" 49 #include "modules/filesystem/FileSystemCallback.h" 50 #include "modules/filesystem/FileWriterBase.h" 51 #include "modules/filesystem/FileWriterBaseCallback.h" 52 #include "modules/filesystem/Metadata.h" 53 #include "modules/filesystem/MetadataCallback.h" 54 55 namespace WebCore { 56 57 FileSystemCallbacksBase::FileSystemCallbacksBase(PassRefPtr<ErrorCallback> errorCallback) 58 : m_errorCallback(errorCallback) 59 , m_blockUntilCompletion(false) 60 { 61 } 62 63 FileSystemCallbacksBase::~FileSystemCallbacksBase() 64 { 65 } 66 67 void FileSystemCallbacksBase::didFail(int code) 68 { 69 if (m_errorCallback) { 70 m_errorCallback->handleEvent(FileError::create(static_cast<FileError::ErrorCode>(code)).get()); 71 m_errorCallback.clear(); 72 } 73 } 74 75 // EntryCallbacks ------------------------------------------------------------- 76 77 PassOwnPtr<EntryCallbacks> EntryCallbacks::create(PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, PassRefPtr<DOMFileSystemBase> fileSystem, const String& expectedPath, bool isDirectory) 78 { 79 return adoptPtr(new EntryCallbacks(successCallback, errorCallback, fileSystem, expectedPath, isDirectory)); 80 } 81 82 EntryCallbacks::EntryCallbacks(PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, PassRefPtr<DOMFileSystemBase> fileSystem, const String& expectedPath, bool isDirectory) 83 : FileSystemCallbacksBase(errorCallback) 84 , m_successCallback(successCallback) 85 , m_fileSystem(fileSystem) 86 , m_expectedPath(expectedPath) 87 , m_isDirectory(isDirectory) 88 { 89 } 90 91 void EntryCallbacks::didSucceed() 92 { 93 if (m_successCallback) { 94 if (m_isDirectory) 95 m_successCallback->handleEvent(DirectoryEntry::create(m_fileSystem, m_expectedPath).get()); 96 else 97 m_successCallback->handleEvent(FileEntry::create(m_fileSystem, m_expectedPath).get()); 98 } 99 m_successCallback.clear(); 100 } 101 102 // EntriesCallbacks ----------------------------------------------------------- 103 104 PassOwnPtr<EntriesCallbacks> EntriesCallbacks::create(PassRefPtr<EntriesCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, PassRefPtr<DirectoryReaderBase> directoryReader, const String& basePath) 105 { 106 return adoptPtr(new EntriesCallbacks(successCallback, errorCallback, directoryReader, basePath)); 107 } 108 109 EntriesCallbacks::EntriesCallbacks(PassRefPtr<EntriesCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, PassRefPtr<DirectoryReaderBase> directoryReader, const String& basePath) 110 : FileSystemCallbacksBase(errorCallback) 111 , m_successCallback(successCallback) 112 , m_directoryReader(directoryReader) 113 , m_basePath(basePath) 114 { 115 ASSERT(m_directoryReader); 116 } 117 118 void EntriesCallbacks::didReadDirectoryEntry(const String& name, bool isDirectory) 119 { 120 if (isDirectory) 121 m_entries.append(DirectoryEntry::create(m_directoryReader->filesystem(), DOMFilePath::append(m_basePath, name))); 122 else 123 m_entries.append(FileEntry::create(m_directoryReader->filesystem(), DOMFilePath::append(m_basePath, name))); 124 } 125 126 void EntriesCallbacks::didReadDirectoryEntries(bool hasMore) 127 { 128 m_directoryReader->setHasMoreEntries(hasMore); 129 if (m_successCallback) 130 m_successCallback->handleEvent(m_entries); 131 } 132 133 // FileSystemCallbacks -------------------------------------------------------- 134 135 PassOwnPtr<FileSystemCallbacks> FileSystemCallbacks::create(PassRefPtr<FileSystemCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, ScriptExecutionContext* scriptExecutionContext, FileSystemType type) 136 { 137 return adoptPtr(new FileSystemCallbacks(successCallback, errorCallback, scriptExecutionContext, type)); 138 } 139 140 FileSystemCallbacks::FileSystemCallbacks(PassRefPtr<FileSystemCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, ScriptExecutionContext* context, FileSystemType type) 141 : FileSystemCallbacksBase(errorCallback) 142 , m_successCallback(successCallback) 143 , m_scriptExecutionContext(context) 144 , m_type(type) 145 { 146 } 147 148 void FileSystemCallbacks::didOpenFileSystem(const String& name, const KURL& rootURL, PassOwnPtr<AsyncFileSystem> asyncFileSystem) 149 { 150 if (m_successCallback) { 151 ASSERT(asyncFileSystem); 152 RefPtr<DOMFileSystem> fileSystem = DOMFileSystem::create(m_scriptExecutionContext.get(), name, m_type, rootURL, asyncFileSystem); 153 m_successCallback->handleEvent(fileSystem.get()); 154 m_scriptExecutionContext.clear(); 155 } 156 m_successCallback.clear(); 157 } 158 159 // ResolveURICallbacks -------------------------------------------------------- 160 161 namespace { 162 163 class ErrorCallbackWrapper : public ErrorCallback { 164 public: 165 static PassRefPtr<ErrorCallbackWrapper> create(PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, PassRefPtr<DirectoryEntry> root, const String& filePath) 166 { 167 return adoptRef(new ErrorCallbackWrapper(successCallback, errorCallback, root, filePath)); 168 } 169 170 virtual bool handleEvent(FileError* error) 171 { 172 ASSERT(error); 173 if (error->code() == FileError::TYPE_MISMATCH_ERR) 174 m_root->getFile(m_filePath, Dictionary(), m_successCallback, m_errorCallback); 175 else if (m_errorCallback) 176 m_errorCallback->handleEvent(error); 177 return true; 178 } 179 180 private: 181 ErrorCallbackWrapper(PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, PassRefPtr<DirectoryEntry> root, const String& filePath) 182 : m_successCallback(successCallback) 183 , m_errorCallback(errorCallback) 184 , m_root(root) 185 , m_filePath(filePath) 186 { 187 ASSERT(m_root); 188 } 189 190 RefPtr<EntryCallback> m_successCallback; 191 RefPtr<ErrorCallback> m_errorCallback; 192 RefPtr<DirectoryEntry> m_root; 193 String m_filePath; 194 }; 195 196 } // namespace 197 198 PassOwnPtr<ResolveURICallbacks> ResolveURICallbacks::create(PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, ScriptExecutionContext* scriptExecutionContext, FileSystemType type, const String& filePath) 199 { 200 return adoptPtr(new ResolveURICallbacks(successCallback, errorCallback, scriptExecutionContext, type, filePath)); 201 } 202 203 ResolveURICallbacks::ResolveURICallbacks(PassRefPtr<EntryCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback, ScriptExecutionContext* context, FileSystemType type, const String& filePath) 204 : FileSystemCallbacksBase(errorCallback) 205 , m_successCallback(successCallback) 206 , m_scriptExecutionContext(context) 207 , m_type(type) 208 , m_filePath(filePath) 209 { 210 } 211 212 void ResolveURICallbacks::didOpenFileSystem(const String& name, const KURL& rootURL, PassOwnPtr<AsyncFileSystem> asyncFileSystem) 213 { 214 ASSERT(asyncFileSystem); 215 RefPtr<DirectoryEntry> root = DOMFileSystem::create(m_scriptExecutionContext.get(), name, m_type, rootURL, asyncFileSystem)->root(); 216 root->getDirectory(m_filePath, Dictionary(), m_successCallback, ErrorCallbackWrapper::create(m_successCallback, m_errorCallback, root, m_filePath)); 217 } 218 219 // MetadataCallbacks ---------------------------------------------------------- 220 221 PassOwnPtr<MetadataCallbacks> MetadataCallbacks::create(PassRefPtr<MetadataCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) 222 { 223 return adoptPtr(new MetadataCallbacks(successCallback, errorCallback)); 224 } 225 226 MetadataCallbacks::MetadataCallbacks(PassRefPtr<MetadataCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) 227 : FileSystemCallbacksBase(errorCallback) 228 , m_successCallback(successCallback) 229 { 230 } 231 232 void MetadataCallbacks::didReadMetadata(const FileMetadata& metadata) 233 { 234 if (m_successCallback) 235 m_successCallback->handleEvent(Metadata::create(metadata).get()); 236 m_successCallback.clear(); 237 } 238 239 // FileWriterBaseCallbacks ---------------------------------------------------------- 240 241 PassOwnPtr<FileWriterBaseCallbacks> FileWriterBaseCallbacks::create(PassRefPtr<FileWriterBase> fileWriter, PassRefPtr<FileWriterBaseCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) 242 { 243 return adoptPtr(new FileWriterBaseCallbacks(fileWriter, successCallback, errorCallback)); 244 } 245 246 FileWriterBaseCallbacks::FileWriterBaseCallbacks(PassRefPtr<FileWriterBase> fileWriter, PassRefPtr<FileWriterBaseCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) 247 : FileSystemCallbacksBase(errorCallback) 248 , m_fileWriter(fileWriter) 249 , m_successCallback(successCallback) 250 { 251 } 252 253 void FileWriterBaseCallbacks::didCreateFileWriter(PassOwnPtr<AsyncFileWriter> asyncFileWriter, long long length) 254 { 255 m_fileWriter->initialize(asyncFileWriter, length); 256 if (m_successCallback) 257 m_successCallback->handleEvent(m_fileWriter.release().get()); 258 m_successCallback.clear(); 259 } 260 261 // VoidCallbacks -------------------------------------------------------------- 262 263 PassOwnPtr<VoidCallbacks> VoidCallbacks::create(PassRefPtr<VoidCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) 264 { 265 return adoptPtr(new VoidCallbacks(successCallback, errorCallback)); 266 } 267 268 VoidCallbacks::VoidCallbacks(PassRefPtr<VoidCallback> successCallback, PassRefPtr<ErrorCallback> errorCallback) 269 : FileSystemCallbacksBase(errorCallback) 270 , m_successCallback(successCallback) 271 { 272 } 273 274 void VoidCallbacks::didSucceed() 275 { 276 if (m_successCallback) 277 m_successCallback->handleEvent(); 278 m_successCallback.clear(); 279 } 280 281 } // namespace 282