Home | History | Annotate | Download | only in filesystem
      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