Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(144)

Side by Side Diff: chrome/browser/chromeos/gdata/gdata_files.cc

Issue 9694016: Extend and refactor GDataFileBase and derived classes. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Created 8 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "chrome/browser/chromeos/gdata/gdata_files.h" 5 #include "chrome/browser/chromeos/gdata/gdata_files.h"
6 6
7 #include <vector> 7 #include <vector>
8 8
9 #include "base/utf_string_conversions.h" 9 #include "base/utf_string_conversions.h"
10 #include "base/platform_file.h" 10 #include "base/platform_file.h"
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 // Paste paths parts back together in reverse order from upward tree 70 // Paste paths parts back together in reverse order from upward tree
71 // traversal. 71 // traversal.
72 for (std::vector<FilePath::StringType>::reverse_iterator iter = 72 for (std::vector<FilePath::StringType>::reverse_iterator iter =
73 parts.rbegin(); 73 parts.rbegin();
74 iter != parts.rend(); ++iter) { 74 iter != parts.rend(); ++iter) {
75 path = path.Append(*iter); 75 path = path.Append(*iter);
76 } 76 }
77 return path; 77 return path;
78 } 78 }
79 79
80 void GDataFileBase::UseOriginalFileName() {
81 file_name_ = EscapeUtf8FileName(original_file_name_);
82 }
83
80 // static. 84 // static.
81 GDataFileBase* GDataFileBase::FromDocumentEntry(GDataDirectory* parent, 85 GDataFileBase* GDataFileBase::FromDocumentEntry(GDataDirectory* parent,
82 DocumentEntry* doc) { 86 DocumentEntry* doc) {
83 DCHECK(parent); 87 DCHECK(parent);
84 DCHECK(doc); 88 DCHECK(doc);
85 if (doc->is_folder()) 89 if (doc->is_folder())
86 return GDataDirectory::FromDocumentEntry(parent, doc); 90 return GDataDirectory::FromDocumentEntry(parent, doc);
87 else if (doc->is_hosted_document() || doc->is_file()) 91 else if (doc->is_hosted_document() || doc->is_file())
88 return GDataFile::FromDocumentEntry(parent, doc); 92 return GDataFile::FromDocumentEntry(parent, doc);
89 93
90 return NULL; 94 return NULL;
91 } 95 }
92 96
93 // static. 97 // static.
94 // Escapes forward slashes from file names with magic unicode character \u2215
95 // pretty much looks the same in UI.
96 std::string GDataFileBase::EscapeUtf8FileName(const std::string& input) { 98 std::string GDataFileBase::EscapeUtf8FileName(const std::string& input) {
97 std::string output; 99 std::string output;
98 if (ReplaceChars(input, kSlash, std::string(kEscapedSlash), &output)) 100 if (ReplaceChars(input, kSlash, std::string(kEscapedSlash), &output))
99 return output; 101 return output;
100 102
101 return input; 103 return input;
102 } 104 }
103 105
104 // static. 106 // static.
105 // Unescapes what was escaped in EScapeUtf8FileName.
106 std::string GDataFileBase::UnescapeUtf8FileName(const std::string& input) { 107 std::string GDataFileBase::UnescapeUtf8FileName(const std::string& input) {
107 std::string output = input; 108 std::string output = input;
108 ReplaceSubstringsAfterOffset(&output, 0, std::string(kEscapedSlash), kSlash); 109 ReplaceSubstringsAfterOffset(&output, 0, std::string(kEscapedSlash), kSlash);
109 return output; 110 return output;
110 } 111 }
111 112
112 // GDataFile class implementation. 113 // GDataFile class implementation.
113 114
114 GDataFile::GDataFile(GDataDirectory* parent) 115 GDataFile::GDataFile(GDataDirectory* parent)
115 : GDataFileBase(parent), 116 : GDataFileBase(parent),
116 kind_(gdata::DocumentEntry::UNKNOWN), 117 kind_(gdata::DocumentEntry::UNKNOWN),
117 is_hosted_document_(false) { 118 is_hosted_document_(false) {
118 DCHECK(parent); 119 DCHECK(parent);
119 } 120 }
120 121
121 GDataFile::~GDataFile() { 122 GDataFile::~GDataFile() {
122 } 123 }
123 124
124 GDataFile* GDataFile::AsGDataFile() { 125 GDataFile* GDataFile::AsGDataFile() {
125 return this; 126 return this;
126 } 127 }
127 128
129 void GDataFile::UseOriginalFileName() {
130 if (is_hosted_document_) {
131 file_name_ = EscapeUtf8FileName(original_file_name_ + document_extension_);
132 } else {
133 GDataFileBase::UseOriginalFileName();
134 }
135 }
136
128 GDataFileBase* GDataFile::FromDocumentEntry(GDataDirectory* parent, 137 GDataFileBase* GDataFile::FromDocumentEntry(GDataDirectory* parent,
129 DocumentEntry* doc) { 138 DocumentEntry* doc) {
130 DCHECK(doc->is_hosted_document() || doc->is_file()); 139 DCHECK(doc->is_hosted_document() || doc->is_file());
131 GDataFile* file = new GDataFile(parent); 140 GDataFile* file = new GDataFile(parent);
141
142 // For regular files, the 'filename' and 'title' attribute in the metadata
143 // may be different (e.g. due to rename). To be consistent with the web
144 // interface and other client to use the 'title' attribute, instead of
145 // 'filename', as the file name in the local snapshot.
146 file->original_file_name_ = UTF16ToUTF8(doc->title());
147
132 // Check if this entry is a true file, or... 148 // Check if this entry is a true file, or...
133 if (doc->is_file()) { 149 if (doc->is_file()) {
134 file->original_file_name_ = UTF16ToUTF8(doc->filename());
135 file->file_name_ =
136 GDataFileBase::EscapeUtf8FileName(file->original_file_name_);
137 file->file_info_.size = doc->file_size(); 150 file->file_info_.size = doc->file_size();
138 file->file_md5_ = doc->file_md5(); 151 file->file_md5_ = doc->file_md5();
139 } else { 152 } else {
140 DCHECK(doc->is_hosted_document());
141 // ... a hosted document. 153 // ... a hosted document.
142 file->original_file_name_ = UTF16ToUTF8(doc->title());
143 // Attach .g<something> extension to hosted documents so we can special 154 // Attach .g<something> extension to hosted documents so we can special
144 // case their handling in UI. 155 // case their handling in UI.
145 // TODO(zelidrag): Figure out better way how to pass entry info like kind 156 // TODO(zelidrag): Figure out better way how to pass entry info like kind
146 // to UI through the File API stack. 157 // to UI through the File API stack.
147 file->file_name_ = GDataFileBase::EscapeUtf8FileName( 158 file->document_extension_ = doc->GetHostedDocumentExtension();
148 file->original_file_name_ + doc->GetHostedDocumentExtension());
149 // We don't know the size of hosted docs and it does not matter since 159 // We don't know the size of hosted docs and it does not matter since
150 // is has no effect on the quota. 160 // is has no effect on the quota.
151 file->file_info_.size = 0; 161 file->file_info_.size = 0;
152 } 162 }
153 file->kind_ = doc->kind(); 163 file->kind_ = doc->kind();
154 const Link* self_link = doc->GetLinkByType(Link::SELF); 164 const Link* self_link = doc->GetLinkByType(Link::SELF);
155 if (self_link) 165 if (self_link)
156 file->self_url_ = self_link->href(); 166 file->self_url_ = self_link->href();
157 file->content_url_ = doc->content_url(); 167 file->content_url_ = doc->content_url();
158 file->content_mime_type_ = doc->content_mime_type(); 168 file->content_mime_type_ = doc->content_mime_type();
159 file->etag_ = doc->etag(); 169 file->etag_ = doc->etag();
160 file->resource_id_ = doc->resource_id(); 170 file->resource_id_ = doc->resource_id();
161 file->id_ = doc->id(); 171 file->id_ = doc->id();
162 file->is_hosted_document_ = doc->is_hosted_document(); 172 file->is_hosted_document_ = doc->is_hosted_document();
163 file->file_info_.last_modified = doc->updated_time(); 173 file->file_info_.last_modified = doc->updated_time();
164 file->file_info_.last_accessed = doc->updated_time(); 174 file->file_info_.last_accessed = doc->updated_time();
165 file->file_info_.creation_time = doc->published_time(); 175 file->file_info_.creation_time = doc->published_time();
166 176
177 // UseOriginalFileName() must be called after |is_hosted_document_| and
178 // |document_extension_| are properly set.
179 file->UseOriginalFileName();
180
167 const Link* thumbnail_link = doc->GetLinkByType(Link::THUMBNAIL); 181 const Link* thumbnail_link = doc->GetLinkByType(Link::THUMBNAIL);
168 if (thumbnail_link) 182 if (thumbnail_link)
169 file->thumbnail_url_ = thumbnail_link->href(); 183 file->thumbnail_url_ = thumbnail_link->href();
170 184
171 const Link* alternate_link = doc->GetLinkByType(Link::ALTERNATE); 185 const Link* alternate_link = doc->GetLinkByType(Link::ALTERNATE);
172 if (alternate_link) 186 if (alternate_link)
173 file->edit_url_ = alternate_link->href(); 187 file->edit_url_ = alternate_link->href();
174 188
175 return file; 189 return file;
176 } 190 }
177 191
178 int GDataFile::GetCacheState() { 192 int GDataFile::GetCacheState() {
179 return root_->GetCacheState(resource(), file_md5()); 193 return root_->GetCacheState(resource_id(), file_md5());
180 } 194 }
181 195
182 // GDataDirectory class implementation. 196 // GDataDirectory class implementation.
183 197
184 GDataDirectory::GDataDirectory(GDataDirectory* parent) 198 GDataDirectory::GDataDirectory(GDataDirectory* parent)
185 : GDataFileBase(parent) { 199 : GDataFileBase(parent) {
186 file_info_.is_directory = true; 200 file_info_.is_directory = true;
187 } 201 }
188 202
189 GDataDirectory::~GDataDirectory() { 203 GDataDirectory::~GDataDirectory() {
190 RemoveChildren(); 204 RemoveChildren();
191 } 205 }
192 206
193 GDataDirectory* GDataDirectory::AsGDataDirectory() { 207 GDataDirectory* GDataDirectory::AsGDataDirectory() {
194 return this; 208 return this;
195 } 209 }
196 210
197 // static 211 // static
198 GDataFileBase* GDataDirectory::FromDocumentEntry(GDataDirectory* parent, 212 GDataFileBase* GDataDirectory::FromDocumentEntry(GDataDirectory* parent,
199 DocumentEntry* doc) { 213 DocumentEntry* doc) {
200 DCHECK(parent); 214 DCHECK(parent);
201 DCHECK(doc->is_folder()); 215 DCHECK(doc->is_folder());
202 GDataDirectory* dir = new GDataDirectory(parent); 216 GDataDirectory* dir = new GDataDirectory(parent);
203 dir->original_file_name_ = UTF16ToUTF8(doc->title()); 217 dir->original_file_name_ = UTF16ToUTF8(doc->title());
204 dir->file_name_ = GDataFileBase::EscapeUtf8FileName(dir->original_file_name_); 218 dir->UseOriginalFileName();
205 dir->file_info_.last_modified = doc->updated_time(); 219 dir->file_info_.last_modified = doc->updated_time();
206 dir->file_info_.last_accessed = doc->updated_time(); 220 dir->file_info_.last_accessed = doc->updated_time();
207 dir->file_info_.creation_time = doc->published_time(); 221 dir->file_info_.creation_time = doc->published_time();
208 // Extract feed link. 222 // Extract feed link.
209 dir->start_feed_url_ = doc->content_url(); 223 dir->start_feed_url_ = doc->content_url();
224 dir->resource_id_ = doc->resource_id();
210 dir->content_url_ = doc->content_url(); 225 dir->content_url_ = doc->content_url();
211 226
227 const Link* self_link = doc->GetLinkByType(Link::SELF);
228 if (self_link)
229 dir->self_url_ = self_link->href();
230
212 const Link* upload_link = doc->GetLinkByType(Link::RESUMABLE_CREATE_MEDIA); 231 const Link* upload_link = doc->GetLinkByType(Link::RESUMABLE_CREATE_MEDIA);
213 if (upload_link) 232 if (upload_link)
214 dir->upload_url_ = upload_link->href(); 233 dir->upload_url_ = upload_link->href();
215 234
216 return dir; 235 return dir;
217 } 236 }
218 237
219 void GDataDirectory::RemoveChildren() { 238 void GDataDirectory::RemoveChildren() {
220 // Remove children from resource map first. 239 // Remove children from resource map first.
221 root_->RemoveFilesFromResourceMap(children_); 240 root_->RemoveFilesFromResourceMap(children_);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 } 272 }
254 } 273 }
255 if (full_file_name.value() != file->file_name()) 274 if (full_file_name.value() != file->file_name())
256 file->set_file_name(full_file_name.value()); 275 file->set_file_name(full_file_name.value());
257 children_.insert(std::make_pair(file->file_name(), file)); 276 children_.insert(std::make_pair(file->file_name(), file));
258 277
259 // Add file to resource map. 278 // Add file to resource map.
260 root_->AddFileToResourceMap(file); 279 root_->AddFileToResourceMap(file);
261 } 280 }
262 281
282 bool GDataDirectory::TakeFile(GDataFileBase* file) {
283 DCHECK(file);
284 DCHECK(file->parent());
285
286 file->parent()->RemoveFileFromChildrenList(file);
287
288 // The file name may have been changed due to prior de-duplication.
289 // We need to first restore the original name of the file before going
290 // through de-duplication again when it is added to another directory
291 file->UseOriginalFileName();
292 AddFile(file);
293
294 // Use GDataFileBase::set_parent() to change the parent of GDataFileBase
295 // as GDataDirectory:AddFile() does not do that.
296 file->set_parent(this);
297 return true;
298 }
299
263 bool GDataDirectory::RemoveFile(GDataFileBase* file) { 300 bool GDataDirectory::RemoveFile(GDataFileBase* file) {
301 DCHECK(file);
302
303 if (!RemoveFileFromChildrenList(file))
304 return false;
305
306 delete file;
307 return true;
308 }
309
310 bool GDataDirectory::RemoveFileFromChildrenList(GDataFileBase* file) {
311 DCHECK(file);
312
264 GDataFileCollection::iterator iter = children_.find(file->file_name()); 313 GDataFileCollection::iterator iter = children_.find(file->file_name());
265 if (iter == children_.end()) 314 if (iter == children_.end())
266 return false; 315 return false;
267 316
268 DCHECK(iter->second); 317 DCHECK(iter->second);
318 DCHECK_EQ(file, iter->second);
269 319
270 // Remove file from resource map first. 320 // Remove file from resource map first.
271 root_->RemoveFileFromResourceMap(file); 321 root_->RemoveFileFromResourceMap(file);
272 322
273 // Then delete it from tree. 323 // Then delete it from tree.
274 delete iter->second;
275 children_.erase(iter); 324 children_.erase(iter);
276 325
277 return true; 326 return true;
278 } 327 }
279 328
280 // GDataRootDirectory class implementation. 329 // GDataRootDirectory class implementation.
281 330
282 GDataRootDirectory::GDataRootDirectory() 331 GDataRootDirectory::GDataRootDirectory()
283 : GDataDirectory(NULL) { 332 : GDataDirectory(NULL) {
284 root_ = this; 333 root_ = this;
285 } 334 }
286 335
287 GDataRootDirectory::~GDataRootDirectory() { 336 GDataRootDirectory::~GDataRootDirectory() {
288 STLDeleteValues(&cache_map_); 337 STLDeleteValues(&cache_map_);
289 cache_map_.clear(); 338 cache_map_.clear();
290 339
291 resource_map_.clear(); 340 resource_map_.clear();
292 } 341 }
293 342
294 GDataRootDirectory* GDataRootDirectory::AsGDataRootDirectory() { 343 GDataRootDirectory* GDataRootDirectory::AsGDataRootDirectory() {
295 return this; 344 return this;
296 } 345 }
297 346
298 void GDataRootDirectory::AddFileToResourceMap(GDataFileBase* file) { 347 void GDataRootDirectory::AddFileToResourceMap(GDataFileBase* file) {
299 // GDataFileSystem has already locked. 348 // GDataFileSystem has already locked.
300 // Only files have resource. 349 // Only files have resource.
301 if (file->AsGDataFile()) { 350 if (file->AsGDataFile()) {
302 resource_map_.insert( 351 resource_map_.insert(
303 std::make_pair(file->AsGDataFile()->resource(), file)); 352 std::make_pair(file->AsGDataFile()->resource_id(), file));
304 } 353 }
305 } 354 }
306 355
307 void GDataRootDirectory::RemoveFileFromResourceMap(GDataFileBase* file) { 356 void GDataRootDirectory::RemoveFileFromResourceMap(GDataFileBase* file) {
308 // GDataFileSystem has already locked. 357 // GDataFileSystem has already locked.
309 if (file->AsGDataFile()) 358 if (file->AsGDataFile())
310 resource_map_.erase(file->AsGDataFile()->resource()); 359 resource_map_.erase(file->AsGDataFile()->resource_id());
311 } 360 }
312 361
313 void GDataRootDirectory::RemoveFilesFromResourceMap( 362 void GDataRootDirectory::RemoveFilesFromResourceMap(
314 const GDataFileCollection& children) { 363 const GDataFileCollection& children) {
315 // GDataFileSystem has already locked. 364 // GDataFileSystem has already locked.
316 for (GDataFileCollection::const_iterator iter = children.begin(); 365 for (GDataFileCollection::const_iterator iter = children.begin();
317 iter != children.end(); ++iter) { 366 iter != children.end(); ++iter) {
318 // Recursively call RemoveFilesFromResourceMap for each directory. 367 // Recursively call RemoveFilesFromResourceMap for each directory.
319 if (iter->second->AsGDataDirectory()) { 368 if (iter->second->AsGDataDirectory()) {
320 RemoveFilesFromResourceMap(iter->second->AsGDataDirectory()->children()); 369 RemoveFilesFromResourceMap(iter->second->AsGDataDirectory()->children());
321 continue; 370 continue;
322 } 371 }
323 372
324 // Only files have resource. 373 // Only files have resource.
325 if (iter->second->AsGDataFile()) 374 if (iter->second->AsGDataFile())
326 resource_map_.erase(iter->second->AsGDataFile()->resource()); 375 resource_map_.erase(iter->second->AsGDataFile()->resource_id());
327 } 376 }
328 } 377 }
329 378
330 GDataFileBase* GDataRootDirectory::GetFileByResource( 379 GDataFileBase* GDataRootDirectory::GetFileByResource(
331 const std::string& resource) { 380 const std::string& resource) {
332 // GDataFileSystem has already locked. 381 // GDataFileSystem has already locked.
333 ResourceMap::const_iterator iter = resource_map_.find(resource); 382 ResourceMap::const_iterator iter = resource_map_.find(resource);
334 if (iter == resource_map_.end()) 383 if (iter == resource_map_.end())
335 return NULL; 384 return NULL;
336 return iter->second; 385 return iter->second;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 cache_state |= GDataFile::CACHE_STATE_PINNED; 467 cache_state |= GDataFile::CACHE_STATE_PINNED;
419 468
420 DVLOG(1) << "Cache state for res_id " << res_id 469 DVLOG(1) << "Cache state for res_id " << res_id
421 << ", md5 " << entry->md5 470 << ", md5 " << entry->md5
422 << ": " << cache_state; 471 << ": " << cache_state;
423 472
424 return cache_state; 473 return cache_state;
425 } 474 }
426 475
427 } // namespace gdata 476 } // namespace gdata
OLDNEW
« chrome/browser/chromeos/gdata/gdata_files.h ('K') | « chrome/browser/chromeos/gdata/gdata_files.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698