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

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
« no previous file with comments | « chrome/browser/chromeos/gdata/gdata_files.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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::SetFileNameFromTitle() {
81 file_name_ = EscapeUtf8FileName(title_);
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::SetFileNameFromTitle() {
130 if (is_hosted_document_) {
131 file_name_ = EscapeUtf8FileName(title_ + document_extension_);
132 } else {
133 GDataFileBase::SetFileNameFromTitle();
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->title_ = 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 // SetFileNameFromTitle() must be called after |title_|,
178 // |is_hosted_document_| and |document_extension_| are set.
179 file->SetFileNameFromTitle();
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->title_ = UTF16ToUTF8(doc->title());
204 dir->file_name_ = GDataFileBase::EscapeUtf8FileName(dir->original_file_name_); 218 // SetFileNameFromTitle() must be called after |title_| is set.
219 dir->SetFileNameFromTitle();
205 dir->file_info_.last_modified = doc->updated_time(); 220 dir->file_info_.last_modified = doc->updated_time();
206 dir->file_info_.last_accessed = doc->updated_time(); 221 dir->file_info_.last_accessed = doc->updated_time();
207 dir->file_info_.creation_time = doc->published_time(); 222 dir->file_info_.creation_time = doc->published_time();
208 // Extract feed link. 223 // Extract feed link.
209 dir->start_feed_url_ = doc->content_url(); 224 dir->start_feed_url_ = doc->content_url();
225 dir->resource_id_ = doc->resource_id();
210 dir->content_url_ = doc->content_url(); 226 dir->content_url_ = doc->content_url();
211 227
228 const Link* self_link = doc->GetLinkByType(Link::SELF);
229 if (self_link)
230 dir->self_url_ = self_link->href();
231
212 const Link* upload_link = doc->GetLinkByType(Link::RESUMABLE_CREATE_MEDIA); 232 const Link* upload_link = doc->GetLinkByType(Link::RESUMABLE_CREATE_MEDIA);
213 if (upload_link) 233 if (upload_link)
214 dir->upload_url_ = upload_link->href(); 234 dir->upload_url_ = upload_link->href();
215 235
216 return dir; 236 return dir;
217 } 237 }
218 238
219 void GDataDirectory::RemoveChildren() { 239 void GDataDirectory::RemoveChildren() {
220 // Remove children from resource map first. 240 // Remove children from resource map first.
221 root_->RemoveFilesFromResourceMap(children_); 241 root_->RemoveFilesFromResourceMap(children_);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 } 273 }
254 } 274 }
255 if (full_file_name.value() != file->file_name()) 275 if (full_file_name.value() != file->file_name())
256 file->set_file_name(full_file_name.value()); 276 file->set_file_name(full_file_name.value());
257 children_.insert(std::make_pair(file->file_name(), file)); 277 children_.insert(std::make_pair(file->file_name(), file));
258 278
259 // Add file to resource map. 279 // Add file to resource map.
260 root_->AddFileToResourceMap(file); 280 root_->AddFileToResourceMap(file);
261 } 281 }
262 282
283 bool GDataDirectory::TakeFile(GDataFileBase* file) {
284 DCHECK(file);
285 DCHECK(file->parent());
286
287 file->parent()->RemoveFileFromChildrenList(file);
288
289 // The file name may have been changed due to prior name de-duplication.
290 // We need to first restore the file name based on the title before going
291 // through name de-duplication again when it is added to another directory.
292 file->SetFileNameFromTitle();
293 AddFile(file);
294
295 // Use GDataFileBase::set_parent() to change the parent of GDataFileBase
296 // as GDataDirectory:AddFile() does not do that.
297 file->set_parent(this);
298 return true;
299 }
300
263 bool GDataDirectory::RemoveFile(GDataFileBase* file) { 301 bool GDataDirectory::RemoveFile(GDataFileBase* file) {
302 DCHECK(file);
303
304 if (!RemoveFileFromChildrenList(file))
305 return false;
306
307 delete file;
308 return true;
309 }
310
311 bool GDataDirectory::RemoveFileFromChildrenList(GDataFileBase* file) {
312 DCHECK(file);
313
264 GDataFileCollection::iterator iter = children_.find(file->file_name()); 314 GDataFileCollection::iterator iter = children_.find(file->file_name());
265 if (iter == children_.end()) 315 if (iter == children_.end())
266 return false; 316 return false;
267 317
268 DCHECK(iter->second); 318 DCHECK(iter->second);
319 DCHECK_EQ(file, iter->second);
269 320
270 // Remove file from resource map first. 321 // Remove file from resource map first.
271 root_->RemoveFileFromResourceMap(file); 322 root_->RemoveFileFromResourceMap(file);
272 323
273 // Then delete it from tree. 324 // Then delete it from tree.
274 delete iter->second;
275 children_.erase(iter); 325 children_.erase(iter);
276 326
277 return true; 327 return true;
278 } 328 }
279 329
280 // GDataRootDirectory class implementation. 330 // GDataRootDirectory class implementation.
281 331
282 GDataRootDirectory::GDataRootDirectory() 332 GDataRootDirectory::GDataRootDirectory()
283 : GDataDirectory(NULL) { 333 : GDataDirectory(NULL) {
284 root_ = this; 334 root_ = this;
285 } 335 }
286 336
287 GDataRootDirectory::~GDataRootDirectory() { 337 GDataRootDirectory::~GDataRootDirectory() {
288 STLDeleteValues(&cache_map_); 338 STLDeleteValues(&cache_map_);
289 cache_map_.clear(); 339 cache_map_.clear();
290 340
291 resource_map_.clear(); 341 resource_map_.clear();
292 } 342 }
293 343
294 GDataRootDirectory* GDataRootDirectory::AsGDataRootDirectory() { 344 GDataRootDirectory* GDataRootDirectory::AsGDataRootDirectory() {
295 return this; 345 return this;
296 } 346 }
297 347
298 void GDataRootDirectory::AddFileToResourceMap(GDataFileBase* file) { 348 void GDataRootDirectory::AddFileToResourceMap(GDataFileBase* file) {
299 // GDataFileSystem has already locked. 349 // GDataFileSystem has already locked.
300 // Only files have resource. 350 // Only files have resource.
301 if (file->AsGDataFile()) { 351 if (file->AsGDataFile()) {
302 resource_map_.insert( 352 resource_map_.insert(
303 std::make_pair(file->AsGDataFile()->resource(), file)); 353 std::make_pair(file->AsGDataFile()->resource_id(), file));
304 } 354 }
305 } 355 }
306 356
307 void GDataRootDirectory::RemoveFileFromResourceMap(GDataFileBase* file) { 357 void GDataRootDirectory::RemoveFileFromResourceMap(GDataFileBase* file) {
308 // GDataFileSystem has already locked. 358 // GDataFileSystem has already locked.
309 if (file->AsGDataFile()) 359 if (file->AsGDataFile())
310 resource_map_.erase(file->AsGDataFile()->resource()); 360 resource_map_.erase(file->AsGDataFile()->resource_id());
311 } 361 }
312 362
313 void GDataRootDirectory::RemoveFilesFromResourceMap( 363 void GDataRootDirectory::RemoveFilesFromResourceMap(
314 const GDataFileCollection& children) { 364 const GDataFileCollection& children) {
315 // GDataFileSystem has already locked. 365 // GDataFileSystem has already locked.
316 for (GDataFileCollection::const_iterator iter = children.begin(); 366 for (GDataFileCollection::const_iterator iter = children.begin();
317 iter != children.end(); ++iter) { 367 iter != children.end(); ++iter) {
318 // Recursively call RemoveFilesFromResourceMap for each directory. 368 // Recursively call RemoveFilesFromResourceMap for each directory.
319 if (iter->second->AsGDataDirectory()) { 369 if (iter->second->AsGDataDirectory()) {
320 RemoveFilesFromResourceMap(iter->second->AsGDataDirectory()->children()); 370 RemoveFilesFromResourceMap(iter->second->AsGDataDirectory()->children());
321 continue; 371 continue;
322 } 372 }
323 373
324 // Only files have resource. 374 // Only files have resource.
325 if (iter->second->AsGDataFile()) 375 if (iter->second->AsGDataFile())
326 resource_map_.erase(iter->second->AsGDataFile()->resource()); 376 resource_map_.erase(iter->second->AsGDataFile()->resource_id());
327 } 377 }
328 } 378 }
329 379
330 GDataFileBase* GDataRootDirectory::GetFileByResource( 380 GDataFileBase* GDataRootDirectory::GetFileByResource(
331 const std::string& resource) { 381 const std::string& resource) {
332 // GDataFileSystem has already locked. 382 // GDataFileSystem has already locked.
333 ResourceMap::const_iterator iter = resource_map_.find(resource); 383 ResourceMap::const_iterator iter = resource_map_.find(resource);
334 if (iter == resource_map_.end()) 384 if (iter == resource_map_.end())
335 return NULL; 385 return NULL;
336 return iter->second; 386 return iter->second;
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
418 cache_state |= GDataFile::CACHE_STATE_PINNED; 468 cache_state |= GDataFile::CACHE_STATE_PINNED;
419 469
420 DVLOG(1) << "Cache state for res_id " << res_id 470 DVLOG(1) << "Cache state for res_id " << res_id
421 << ", md5 " << entry->md5 471 << ", md5 " << entry->md5
422 << ": " << cache_state; 472 << ": " << cache_state;
423 473
424 return cache_state; 474 return cache_state;
425 } 475 }
426 476
427 } // namespace gdata 477 } // namespace gdata
OLDNEW
« no previous file with comments | « 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