| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <utility> | 5 #include <utility> |
| 6 | 6 |
| 7 #include "base/metrics/histogram.h" | 7 #include "base/metrics/histogram.h" |
| 8 #include "chrome/browser/chromeos/gdata/drive_resource_metadata.h" |
| 8 #include "chrome/browser/chromeos/gdata/drive_files.h" | 9 #include "chrome/browser/chromeos/gdata/drive_files.h" |
| 9 #include "chrome/browser/chromeos/gdata/gdata_directory_service.h" | |
| 10 #include "chrome/browser/chromeos/gdata/gdata_wapi_feed_processor.h" | 10 #include "chrome/browser/chromeos/gdata/gdata_wapi_feed_processor.h" |
| 11 #include "content/public/browser/browser_thread.h" | 11 #include "content/public/browser/browser_thread.h" |
| 12 | 12 |
| 13 using content::BrowserThread; | 13 using content::BrowserThread; |
| 14 | 14 |
| 15 namespace gdata { | 15 namespace gdata { |
| 16 | 16 |
| 17 FeedToFileResourceMapUmaStats::FeedToFileResourceMapUmaStats() | 17 FeedToFileResourceMapUmaStats::FeedToFileResourceMapUmaStats() |
| 18 : num_regular_files(0), | 18 : num_regular_files(0), |
| 19 num_hosted_documents(0) { | 19 num_hosted_documents(0) { |
| 20 } | 20 } |
| 21 | 21 |
| 22 FeedToFileResourceMapUmaStats::~FeedToFileResourceMapUmaStats() { | 22 FeedToFileResourceMapUmaStats::~FeedToFileResourceMapUmaStats() { |
| 23 } | 23 } |
| 24 | 24 |
| 25 GDataWapiFeedProcessor::GDataWapiFeedProcessor( | 25 GDataWapiFeedProcessor::GDataWapiFeedProcessor( |
| 26 GDataDirectoryService* directory_service) | 26 DriveResourceMetadata* resource_metadata) |
| 27 : directory_service_(directory_service) { | 27 : resource_metadata_(resource_metadata) { |
| 28 } | 28 } |
| 29 | 29 |
| 30 GDataWapiFeedProcessor::~GDataWapiFeedProcessor() { | 30 GDataWapiFeedProcessor::~GDataWapiFeedProcessor() { |
| 31 } | 31 } |
| 32 | 32 |
| 33 GDataFileError GDataWapiFeedProcessor::ApplyFeeds( | 33 GDataFileError GDataWapiFeedProcessor::ApplyFeeds( |
| 34 const std::vector<DocumentFeed*>& feed_list, | 34 const std::vector<DocumentFeed*>& feed_list, |
| 35 int64 start_changestamp, | 35 int64 start_changestamp, |
| 36 int64 root_feed_changestamp, | 36 int64 root_feed_changestamp, |
| 37 std::set<FilePath>* changed_dirs) { | 37 std::set<FilePath>* changed_dirs) { |
| 38 bool is_delta_feed = start_changestamp != 0; | 38 bool is_delta_feed = start_changestamp != 0; |
| 39 | 39 |
| 40 directory_service_->set_origin(FROM_SERVER); | 40 resource_metadata_->set_origin(FROM_SERVER); |
| 41 | 41 |
| 42 int64 delta_feed_changestamp = 0; | 42 int64 delta_feed_changestamp = 0; |
| 43 FeedToFileResourceMapUmaStats uma_stats; | 43 FeedToFileResourceMapUmaStats uma_stats; |
| 44 FileResourceIdMap file_map; | 44 FileResourceIdMap file_map; |
| 45 GDataFileError error = FeedToFileResourceMap(feed_list, | 45 GDataFileError error = FeedToFileResourceMap(feed_list, |
| 46 &file_map, | 46 &file_map, |
| 47 &delta_feed_changestamp, | 47 &delta_feed_changestamp, |
| 48 &uma_stats); | 48 &uma_stats); |
| 49 if (error != GDATA_FILE_OK) | 49 if (error != GDATA_FILE_OK) |
| 50 return error; | 50 return error; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 87 | 87 |
| 88 void GDataWapiFeedProcessor::ApplyFeedFromFileUrlMap( | 88 void GDataWapiFeedProcessor::ApplyFeedFromFileUrlMap( |
| 89 bool is_delta_feed, | 89 bool is_delta_feed, |
| 90 int64 feed_changestamp, | 90 int64 feed_changestamp, |
| 91 FileResourceIdMap* file_map, | 91 FileResourceIdMap* file_map, |
| 92 std::set<FilePath>* changed_dirs) { | 92 std::set<FilePath>* changed_dirs) { |
| 93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 93 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 94 DCHECK(changed_dirs); | 94 DCHECK(changed_dirs); |
| 95 | 95 |
| 96 if (!is_delta_feed) { // Full update. | 96 if (!is_delta_feed) { // Full update. |
| 97 directory_service_->root()->RemoveChildren(); | 97 resource_metadata_->root()->RemoveChildren(); |
| 98 changed_dirs->insert(directory_service_->root()->GetFilePath()); | 98 changed_dirs->insert(resource_metadata_->root()->GetFilePath()); |
| 99 } | 99 } |
| 100 directory_service_->set_largest_changestamp(feed_changestamp); | 100 resource_metadata_->set_largest_changestamp(feed_changestamp); |
| 101 | 101 |
| 102 scoped_ptr<GDataDirectoryService> orphaned_dir_service( | 102 scoped_ptr<DriveResourceMetadata> orphaned_resources( |
| 103 new GDataDirectoryService); | 103 new DriveResourceMetadata); |
| 104 // Go through all entries generated by the feed and apply them to the local | 104 // Go through all entries generated by the feed and apply them to the local |
| 105 // snapshot of the file system. | 105 // snapshot of the file system. |
| 106 for (FileResourceIdMap::iterator it = file_map->begin(); | 106 for (FileResourceIdMap::iterator it = file_map->begin(); |
| 107 it != file_map->end();) { | 107 it != file_map->end();) { |
| 108 // Ensure that the entry is deleted, unless the ownership is explicitly | 108 // Ensure that the entry is deleted, unless the ownership is explicitly |
| 109 // transferred by entry.release(). | 109 // transferred by entry.release(). |
| 110 scoped_ptr<DriveEntry> entry(it->second); | 110 scoped_ptr<DriveEntry> entry(it->second); |
| 111 DCHECK_EQ(it->first, entry->resource_id()); | 111 DCHECK_EQ(it->first, entry->resource_id()); |
| 112 // Erase the entry so the deleted entry won't be referenced. | 112 // Erase the entry so the deleted entry won't be referenced. |
| 113 file_map->erase(it++); | 113 file_map->erase(it++); |
| 114 | 114 |
| 115 DriveEntry* old_entry = | 115 DriveEntry* old_entry = |
| 116 directory_service_->GetEntryByResourceId(entry->resource_id()); | 116 resource_metadata_->GetEntryByResourceId(entry->resource_id()); |
| 117 DriveDirectory* dest_dir = NULL; | 117 DriveDirectory* dest_dir = NULL; |
| 118 if (entry->is_deleted()) { // Deleted file/directory. | 118 if (entry->is_deleted()) { // Deleted file/directory. |
| 119 DVLOG(1) << "Removing file " << entry->base_name(); | 119 DVLOG(1) << "Removing file " << entry->base_name(); |
| 120 if (!old_entry) | 120 if (!old_entry) |
| 121 continue; | 121 continue; |
| 122 | 122 |
| 123 dest_dir = old_entry->parent(); | 123 dest_dir = old_entry->parent(); |
| 124 if (!dest_dir) { | 124 if (!dest_dir) { |
| 125 NOTREACHED(); | 125 NOTREACHED(); |
| 126 continue; | 126 continue; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 142 old_entry->AsDriveDirectory()); | 142 old_entry->AsDriveDirectory()); |
| 143 } | 143 } |
| 144 // Remove the old instance of this entry. | 144 // Remove the old instance of this entry. |
| 145 RemoveEntryFromDirectoryAndCollectChangedDirectories( | 145 RemoveEntryFromDirectoryAndCollectChangedDirectories( |
| 146 dest_dir, old_entry, changed_dirs); | 146 dest_dir, old_entry, changed_dirs); |
| 147 // Did we actually move the new file to another directory? | 147 // Did we actually move the new file to another directory? |
| 148 if (dest_dir->resource_id() != entry->parent_resource_id()) { | 148 if (dest_dir->resource_id() != entry->parent_resource_id()) { |
| 149 changed_dirs->insert(dest_dir->GetFilePath()); | 149 changed_dirs->insert(dest_dir->GetFilePath()); |
| 150 dest_dir = FindDirectoryForNewEntry(entry.get(), | 150 dest_dir = FindDirectoryForNewEntry(entry.get(), |
| 151 *file_map, | 151 *file_map, |
| 152 orphaned_dir_service.get()); | 152 orphaned_resources.get()); |
| 153 } | 153 } |
| 154 DCHECK(dest_dir); | 154 DCHECK(dest_dir); |
| 155 AddEntryToDirectoryAndCollectChangedDirectories( | 155 AddEntryToDirectoryAndCollectChangedDirectories( |
| 156 entry.release(), | 156 entry.release(), |
| 157 dest_dir, | 157 dest_dir, |
| 158 orphaned_dir_service.get(), | 158 orphaned_resources.get(), |
| 159 changed_dirs); | 159 changed_dirs); |
| 160 } else { // Adding a new file. | 160 } else { // Adding a new file. |
| 161 dest_dir = FindDirectoryForNewEntry(entry.get(), | 161 dest_dir = FindDirectoryForNewEntry(entry.get(), |
| 162 *file_map, | 162 *file_map, |
| 163 orphaned_dir_service.get()); | 163 orphaned_resources.get()); |
| 164 DCHECK(dest_dir); | 164 DCHECK(dest_dir); |
| 165 AddEntryToDirectoryAndCollectChangedDirectories( | 165 AddEntryToDirectoryAndCollectChangedDirectories( |
| 166 entry.release(), | 166 entry.release(), |
| 167 dest_dir, | 167 dest_dir, |
| 168 orphaned_dir_service.get(), | 168 orphaned_resources.get(), |
| 169 changed_dirs); | 169 changed_dirs); |
| 170 } | 170 } |
| 171 | 171 |
| 172 // Record changed directory if this was a delta feed and the parent | 172 // Record changed directory if this was a delta feed and the parent |
| 173 // directory is already properly rooted within its parent. | 173 // directory is already properly rooted within its parent. |
| 174 if (dest_dir && (dest_dir->parent() || | 174 if (dest_dir && (dest_dir->parent() || |
| 175 dest_dir == directory_service_->root()) && | 175 dest_dir == resource_metadata_->root()) && |
| 176 dest_dir != orphaned_dir_service->root() && is_delta_feed) { | 176 dest_dir != orphaned_resources->root() && is_delta_feed) { |
| 177 changed_dirs->insert(dest_dir->GetFilePath()); | 177 changed_dirs->insert(dest_dir->GetFilePath()); |
| 178 } | 178 } |
| 179 } | 179 } |
| 180 // All entry must be erased from the map. | 180 // All entry must be erased from the map. |
| 181 DCHECK(file_map->empty()); | 181 DCHECK(file_map->empty()); |
| 182 } | 182 } |
| 183 | 183 |
| 184 // static | 184 // static |
| 185 void GDataWapiFeedProcessor::AddEntryToDirectoryAndCollectChangedDirectories( | 185 void GDataWapiFeedProcessor::AddEntryToDirectoryAndCollectChangedDirectories( |
| 186 DriveEntry* entry, | 186 DriveEntry* entry, |
| 187 DriveDirectory* directory, | 187 DriveDirectory* directory, |
| 188 GDataDirectoryService* orphaned_dir_service, | 188 DriveResourceMetadata* orphaned_resources, |
| 189 std::set<FilePath>* changed_dirs) { | 189 std::set<FilePath>* changed_dirs) { |
| 190 directory->AddEntry(entry); | 190 directory->AddEntry(entry); |
| 191 if (entry->AsDriveDirectory() && directory != orphaned_dir_service->root()) | 191 if (entry->AsDriveDirectory() && directory != orphaned_resources->root()) |
| 192 changed_dirs->insert(entry->GetFilePath()); | 192 changed_dirs->insert(entry->GetFilePath()); |
| 193 } | 193 } |
| 194 | 194 |
| 195 // static | 195 // static |
| 196 void GDataWapiFeedProcessor:: | 196 void GDataWapiFeedProcessor:: |
| 197 RemoveEntryFromDirectoryAndCollectChangedDirectories( | 197 RemoveEntryFromDirectoryAndCollectChangedDirectories( |
| 198 DriveDirectory* directory, | 198 DriveDirectory* directory, |
| 199 DriveEntry* entry, | 199 DriveEntry* entry, |
| 200 std::set<FilePath>* changed_dirs) { | 200 std::set<FilePath>* changed_dirs) { |
| 201 // Get the list of all sub-directory paths, so we can notify their listeners | 201 // Get the list of all sub-directory paths, so we can notify their listeners |
| 202 // that they are smoked. | 202 // that they are smoked. |
| 203 DriveDirectory* dir = entry->AsDriveDirectory(); | 203 DriveDirectory* dir = entry->AsDriveDirectory(); |
| 204 if (dir) | 204 if (dir) |
| 205 dir->GetChildDirectoryPaths(changed_dirs); | 205 dir->GetChildDirectoryPaths(changed_dirs); |
| 206 directory->RemoveEntry(entry); | 206 directory->RemoveEntry(entry); |
| 207 } | 207 } |
| 208 | 208 |
| 209 DriveDirectory* GDataWapiFeedProcessor::FindDirectoryForNewEntry( | 209 DriveDirectory* GDataWapiFeedProcessor::FindDirectoryForNewEntry( |
| 210 DriveEntry* new_entry, | 210 DriveEntry* new_entry, |
| 211 const FileResourceIdMap& file_map, | 211 const FileResourceIdMap& file_map, |
| 212 GDataDirectoryService* orphaned_dir_service) { | 212 DriveResourceMetadata* orphaned_resources) { |
| 213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 213 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 214 DriveDirectory* dir = NULL; | 214 DriveDirectory* dir = NULL; |
| 215 // Added file. | 215 // Added file. |
| 216 const std::string& parent_id = new_entry->parent_resource_id(); | 216 const std::string& parent_id = new_entry->parent_resource_id(); |
| 217 if (parent_id.empty()) { | 217 if (parent_id.empty()) { |
| 218 dir = directory_service_->root(); | 218 dir = resource_metadata_->root(); |
| 219 DVLOG(1) << "Root parent for " << new_entry->base_name(); | 219 DVLOG(1) << "Root parent for " << new_entry->base_name(); |
| 220 } else { | 220 } else { |
| 221 DriveEntry* entry = directory_service_->GetEntryByResourceId(parent_id); | 221 DriveEntry* entry = resource_metadata_->GetEntryByResourceId(parent_id); |
| 222 dir = entry ? entry->AsDriveDirectory() : NULL; | 222 dir = entry ? entry->AsDriveDirectory() : NULL; |
| 223 if (!dir) { | 223 if (!dir) { |
| 224 // The parent directory was also added with this set of feeds. | 224 // The parent directory was also added with this set of feeds. |
| 225 FileResourceIdMap::const_iterator find_iter = | 225 FileResourceIdMap::const_iterator find_iter = |
| 226 file_map.find(parent_id); | 226 file_map.find(parent_id); |
| 227 dir = (find_iter != file_map.end() && | 227 dir = (find_iter != file_map.end() && |
| 228 find_iter->second) ? | 228 find_iter->second) ? |
| 229 find_iter->second->AsDriveDirectory() : NULL; | 229 find_iter->second->AsDriveDirectory() : NULL; |
| 230 if (dir) { | 230 if (dir) { |
| 231 DVLOG(1) << "Found parent for " << new_entry->base_name() | 231 DVLOG(1) << "Found parent for " << new_entry->base_name() |
| 232 << " in file_map " << parent_id; | 232 << " in file_map " << parent_id; |
| 233 } else { | 233 } else { |
| 234 DVLOG(1) << "Adding orphan " << new_entry->GetFilePath().value(); | 234 DVLOG(1) << "Adding orphan " << new_entry->GetFilePath().value(); |
| 235 dir = orphaned_dir_service->root(); | 235 dir = orphaned_resources->root(); |
| 236 } | 236 } |
| 237 } | 237 } |
| 238 } | 238 } |
| 239 return dir; | 239 return dir; |
| 240 } | 240 } |
| 241 | 241 |
| 242 GDataFileError GDataWapiFeedProcessor::FeedToFileResourceMap( | 242 GDataFileError GDataWapiFeedProcessor::FeedToFileResourceMap( |
| 243 const std::vector<DocumentFeed*>& feed_list, | 243 const std::vector<DocumentFeed*>& feed_list, |
| 244 FileResourceIdMap* file_map, | 244 FileResourceIdMap* file_map, |
| 245 int64* feed_changestamp, | 245 int64* feed_changestamp, |
| 246 FeedToFileResourceMapUmaStats* uma_stats) { | 246 FeedToFileResourceMapUmaStats* uma_stats) { |
| 247 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 247 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 248 DCHECK(uma_stats); | 248 DCHECK(uma_stats); |
| 249 | 249 |
| 250 GDataFileError error = GDATA_FILE_OK; | 250 GDataFileError error = GDATA_FILE_OK; |
| 251 uma_stats->num_regular_files = 0; | 251 uma_stats->num_regular_files = 0; |
| 252 uma_stats->num_hosted_documents = 0; | 252 uma_stats->num_hosted_documents = 0; |
| 253 uma_stats->num_files_with_entry_kind.clear(); | 253 uma_stats->num_files_with_entry_kind.clear(); |
| 254 for (size_t i = 0; i < feed_list.size(); ++i) { | 254 for (size_t i = 0; i < feed_list.size(); ++i) { |
| 255 const DocumentFeed* feed = feed_list[i]; | 255 const DocumentFeed* feed = feed_list[i]; |
| 256 | 256 |
| 257 // Get upload url from the root feed. Links for all other collections will | 257 // Get upload url from the root feed. Links for all other collections will |
| 258 // be handled in GDatadirectory::FromDocumentEntry(); | 258 // be handled in GDatadirectory::FromDocumentEntry(); |
| 259 if (i == 0) { | 259 if (i == 0) { |
| 260 const Link* root_feed_upload_link = | 260 const Link* root_feed_upload_link = |
| 261 feed->GetLinkByType(Link::RESUMABLE_CREATE_MEDIA); | 261 feed->GetLinkByType(Link::RESUMABLE_CREATE_MEDIA); |
| 262 if (root_feed_upload_link) | 262 if (root_feed_upload_link) |
| 263 directory_service_->root()->set_upload_url( | 263 resource_metadata_->root()->set_upload_url( |
| 264 root_feed_upload_link->href()); | 264 root_feed_upload_link->href()); |
| 265 *feed_changestamp = feed->largest_changestamp(); | 265 *feed_changestamp = feed->largest_changestamp(); |
| 266 DCHECK_GE(*feed_changestamp, 0); | 266 DCHECK_GE(*feed_changestamp, 0); |
| 267 } | 267 } |
| 268 | 268 |
| 269 for (ScopedVector<DocumentEntry>::const_iterator iter = | 269 for (ScopedVector<DocumentEntry>::const_iterator iter = |
| 270 feed->entries().begin(); | 270 feed->entries().begin(); |
| 271 iter != feed->entries().end(); ++iter) { | 271 iter != feed->entries().end(); ++iter) { |
| 272 DocumentEntry* doc = *iter; | 272 DocumentEntry* doc = *iter; |
| 273 DriveEntry* entry = directory_service_->FromDocumentEntry(*doc); | 273 DriveEntry* entry = resource_metadata_->FromDocumentEntry(*doc); |
| 274 // Some document entries don't map into files (i.e. sites). | 274 // Some document entries don't map into files (i.e. sites). |
| 275 if (!entry) | 275 if (!entry) |
| 276 continue; | 276 continue; |
| 277 // Count the number of files. | 277 // Count the number of files. |
| 278 DriveFile* as_file = entry->AsDriveFile(); | 278 DriveFile* as_file = entry->AsDriveFile(); |
| 279 if (as_file) { | 279 if (as_file) { |
| 280 if (as_file->is_hosted_document()) | 280 if (as_file->is_hosted_document()) |
| 281 ++uma_stats->num_hosted_documents; | 281 ++uma_stats->num_hosted_documents; |
| 282 else | 282 else |
| 283 ++uma_stats->num_regular_files; | 283 ++uma_stats->num_regular_files; |
| (...skipping 22 matching lines...) Expand all Loading... |
| 306 // If the code above fails to parse a feed, any DriveEntry instance | 306 // If the code above fails to parse a feed, any DriveEntry instance |
| 307 // added to |file_by_url| is not managed by a DriveDirectory instance, | 307 // added to |file_by_url| is not managed by a DriveDirectory instance, |
| 308 // so we need to explicitly release them here. | 308 // so we need to explicitly release them here. |
| 309 STLDeleteValues(file_map); | 309 STLDeleteValues(file_map); |
| 310 } | 310 } |
| 311 | 311 |
| 312 return error; | 312 return error; |
| 313 } | 313 } |
| 314 | 314 |
| 315 } // namespace gdata | 315 } // namespace gdata |
| OLD | NEW |