change_list_processor.h revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
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. 4 5#ifndef CHROME_BROWSER_CHROMEOS_DRIVE_CHANGE_LIST_PROCESSOR_H_ 6#define CHROME_BROWSER_CHROMEOS_DRIVE_CHANGE_LIST_PROCESSOR_H_ 7 8#include <map> 9#include <set> 10#include <string> 11 12#include "base/callback.h" 13#include "base/files/file_path.h" 14#include "base/memory/scoped_ptr.h" 15#include "base/memory/scoped_vector.h" 16#include "base/memory/weak_ptr.h" 17#include "chrome/browser/chromeos/drive/file_errors.h" 18#include "googleurl/src/gurl.h" 19 20namespace google_apis { 21class AboutResource; 22class ResourceList; 23} // google_apis 24 25namespace drive { 26 27class ResourceEntry; 28 29namespace internal { 30class ResourceMetadata; 31} // namespace internal 32 33// Class to represent a change list. 34class ChangeList { 35 public: 36 explicit ChangeList(const google_apis::ResourceList& resource_list); 37 ~ChangeList(); 38 39 const std::vector<ResourceEntry>& entries() const { return entries_; } 40 std::vector<ResourceEntry>* mutable_entries() { return &entries_; } 41 const GURL& next_url() const { return next_url_; } 42 int64 largest_changestamp() const { return largest_changestamp_; } 43 44 private: 45 std::vector<ResourceEntry> entries_; 46 GURL next_url_; 47 int64 largest_changestamp_; 48 49 DISALLOW_COPY_AND_ASSIGN(ChangeList); 50}; 51 52// ChangeListProcessor is used to process feeds from WAPI (codename for 53// Documents List API) or Google Drive API. 54class ChangeListProcessor { 55 public: 56 typedef std::map<std::string /* resource_id */, ResourceEntry> 57 ResourceEntryMap; 58 59 // Class used to record UMA stats with FeedToEntryProtoMap(). 60 class ChangeListToEntryProtoMapUMAStats; 61 62 explicit ChangeListProcessor(internal::ResourceMetadata* resource_metadata); 63 ~ChangeListProcessor(); 64 65 // Applies the documents feeds to the file system using |resource_metadata_|. 66 // 67 // |is_delta_feed| determines the type of feed to process, whether it is a 68 // root feed (false) or a delta feed (true). 69 // 70 // In the case of processing the root feeds |root_feed_changestamp| is used 71 // as its initial changestamp value. The value comes from 72 // google_apis::AccountMetadata. 73 // |on_complete_callback| is run after the feed is applied. 74 // |on_complete_callback| must not be null. 75 // TODO(achuith): Change the type of on_complete_callback to 76 // FileOperationCallback instead. 77 void ApplyFeeds(scoped_ptr<google_apis::AboutResource> about_resource, 78 ScopedVector<ChangeList> change_lists, 79 bool is_delta_feed, 80 const base::Closure& on_complete_callback); 81 82 // Converts list of document feeds from collected feeds into a 83 // ResourceEntryMap. |feed_changestamp| and/or |uma_stats| may be NULL. 84 // entry_map_ is updated as side effects. 85 void FeedToEntryProtoMap(ScopedVector<ChangeList> change_lists, 86 int64* feed_changestamp, 87 ChangeListToEntryProtoMapUMAStats* uma_stats); 88 89 // A map of ResourceEntry's representing a feed. 90 const ResourceEntryMap& entry_map() const { return entry_map_; } 91 92 // The set of changed directories as a result of feed processing. 93 const std::set<base::FilePath>& changed_dirs() const { return changed_dirs_; } 94 95 private: 96 // Applies the pre-processed feed from entry_map_ onto the filesystem. 97 // If this is not delta feed update (i.e. |is_delta_feed| is false), 98 // |about_resource| must not be null. 99 void ApplyEntryProtoMap( 100 bool is_delta_feed, 101 scoped_ptr<google_apis::AboutResource> about_resource); 102 void ApplyEntryProtoMapAfterReset( 103 scoped_ptr<google_apis::AboutResource> about_resource, 104 FileError error); 105 106 // Apply the next item from entry_map_ to the file system. The async 107 // version posts to the message loop to avoid recursive stack-overflow. 108 void ApplyNextEntryProto(); 109 void ApplyNextEntryProtoAsync(); 110 111 // Apply |entry| to resource_metadata_. 112 void ApplyEntryProto(const ResourceEntry& entry); 113 114 // Continue ApplyEntryProto. This is a callback for 115 // ResourceMetadata::GetEntryInfoByResourceId. 116 void ContinueApplyEntryProto( 117 const ResourceEntry& entry, 118 FileError error, 119 const base::FilePath& file_path, 120 scoped_ptr<ResourceEntry> old_entry); 121 122 // Apply the ResourceEntry pointed to by |it| to resource_metadata_. 123 void ApplyNextByIterator(ResourceEntryMap::iterator it); 124 125 // Helper function to add |entry| to its parent. Updates changed_dirs_ 126 // as a side effect. 127 void AddEntry(const ResourceEntry& entry); 128 129 // Callback for ResourceMetadata::AddEntry. 130 void NotifyForAddEntry(bool is_directory, 131 FileError error, 132 const base::FilePath& file_path); 133 134 // Removes entry pointed to by |resource_id| from its parent. Updates 135 // changed_dirs_ as a side effect. 136 void RemoveEntryFromParent( 137 const ResourceEntry& entry, 138 const base::FilePath& file_path); 139 140 // Continues RemoveEntryFromParent after 141 // ResourceMetadata::GetChildDirectories. 142 void OnGetChildrenForRemove( 143 const ResourceEntry& entry, 144 const base::FilePath& file_path, 145 const std::set<base::FilePath>& child_directories); 146 147 // Callback for ResourceMetadata::RemoveEntryFromParent. 148 void NotifyForRemoveEntryFromParent( 149 bool is_directory, 150 const base::FilePath& file_path, 151 const std::set<base::FilePath>& child_directories, 152 FileError error, 153 const base::FilePath& parent_path); 154 155 // Refreshes ResourceMetadata entry that has the same resource_id as 156 // |entry| with |entry|. Updates changed_dirs_ as a side effect. 157 void RefreshEntry(const ResourceEntry& entry, 158 const base::FilePath& file_path); 159 160 // Callback for ResourceMetadata::RefreshEntry. 161 void NotifyForRefreshEntry( 162 const base::FilePath& old_file_path, 163 FileError error, 164 const base::FilePath& file_path, 165 scoped_ptr<ResourceEntry> entry); 166 167 // Updates the root directory entry. changestamp will be updated. Calls 168 // |closure| upon completion regardless of whether the update was successful 169 // or not. |closure| must not be null. 170 void UpdateRootEntry(const base::Closure& closure); 171 172 // Part of UpdateRootEntry(). Called after 173 // ResourceMetadata::GetEntryInfoByPath is complete. Updates the root 174 // proto, and refreshes the root entry with the proto. 175 void UpdateRootEntryAfterGetEntry(const base::Closure& closure, 176 FileError error, 177 scoped_ptr<ResourceEntry> root_proto); 178 179 // Part of UpdateRootEntry(). Called after 180 // ResourceMetadata::RefreshEntry() is complete. Calls OnComplete() to 181 // finish the change list processing. 182 void UpdateRootEntryAfterRefreshEntry(const base::Closure& closure, 183 FileError error, 184 const base::FilePath& root_path, 185 scoped_ptr<ResourceEntry> root_proto); 186 187 // Runs after all entries have been processed. 188 void OnComplete(); 189 190 // Reset the state of this object. 191 void Clear(); 192 193 internal::ResourceMetadata* resource_metadata_; // Not owned. 194 195 ResourceEntryMap entry_map_; 196 std::set<base::FilePath> changed_dirs_; 197 int64 largest_changestamp_; 198 base::Closure on_complete_callback_; 199 200 // Note: This should remain the last member so it'll be destroyed and 201 // invalidate its weak pointers before any other members are destroyed. 202 base::WeakPtrFactory<ChangeListProcessor> weak_ptr_factory_; 203 DISALLOW_COPY_AND_ASSIGN(ChangeListProcessor); 204}; 205 206} // namespace drive 207 208#endif // CHROME_BROWSER_CHROMEOS_DRIVE_CHANGE_LIST_PROCESSOR_H_ 209