drive_backend_util.cc revision f2477e01787aa58f445919b809d89e252beef54f
1// Copyright 2013 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#include "chrome/browser/sync_file_system/drive_backend/drive_backend_util.h" 6 7#include "base/file_util.h" 8#include "base/logging.h" 9#include "base/memory/scoped_vector.h" 10#include "base/message_loop/message_loop_proxy.h" 11#include "base/strings/string_number_conversions.h" 12#include "chrome/browser/drive/drive_api_util.h" 13#include "chrome/browser/google_apis/drive_api_parser.h" 14#include "chrome/browser/google_apis/gdata_wapi_parser.h" 15#include "chrome/browser/sync_file_system/drive_backend/drive_backend_constants.h" 16#include "chrome/browser/sync_file_system/drive_backend/metadata_database.pb.h" 17#include "net/base/mime_util.h" 18#include "third_party/leveldatabase/src/include/leveldb/write_batch.h" 19 20namespace sync_file_system { 21namespace drive_backend { 22 23namespace { 24 25const char kMimeTypeOctetStream[] = "application/octet-stream"; 26 27} // namespace 28 29void PutServiceMetadataToBatch(const ServiceMetadata& service_metadata, 30 leveldb::WriteBatch* batch) { 31 std::string value; 32 bool success = service_metadata.SerializeToString(&value); 33 DCHECK(success); 34 batch->Put(kServiceMetadataKey, value); 35} 36 37void PutFileToBatch(const FileMetadata& file, leveldb::WriteBatch* batch) { 38 std::string value; 39 bool success = file.SerializeToString(&value); 40 DCHECK(success); 41 batch->Put(kFileMetadataKeyPrefix + file.file_id(), value); 42} 43 44void PutTrackerToBatch(const FileTracker& tracker, leveldb::WriteBatch* batch) { 45 std::string value; 46 bool success = tracker.SerializeToString(&value); 47 DCHECK(success); 48 batch->Put(kFileTrackerKeyPrefix + base::Int64ToString(tracker.tracker_id()), 49 value); 50} 51 52void PopulateFileDetailsByFileResource( 53 const google_apis::FileResource& file_resource, 54 FileDetails* details) { 55 details->clear_parent_folder_ids(); 56 for (ScopedVector<google_apis::ParentReference>::const_iterator itr = 57 file_resource.parents().begin(); 58 itr != file_resource.parents().end(); 59 ++itr) { 60 details->add_parent_folder_ids((*itr)->file_id()); 61 } 62 details->set_title(file_resource.title()); 63 64 google_apis::DriveEntryKind kind = drive::util::GetKind(file_resource); 65 if (kind == google_apis::ENTRY_KIND_FILE) 66 details->set_file_kind(FILE_KIND_FILE); 67 else if (kind == google_apis::ENTRY_KIND_FOLDER) 68 details->set_file_kind(FILE_KIND_FOLDER); 69 else 70 details->set_file_kind(FILE_KIND_UNSUPPORTED); 71 72 details->set_md5(file_resource.md5_checksum()); 73 details->set_etag(file_resource.etag()); 74 details->set_creation_time(file_resource.created_date().ToInternalValue()); 75 details->set_modification_time( 76 file_resource.modified_date().ToInternalValue()); 77 details->set_missing(false); 78} 79 80scoped_ptr<FileMetadata> CreateFileMetadataFromFileResource( 81 int64 change_id, 82 const google_apis::FileResource& resource) { 83 scoped_ptr<FileMetadata> file(new FileMetadata); 84 file->set_file_id(resource.file_id()); 85 86 FileDetails* details = file->mutable_details(); 87 details->set_change_id(change_id); 88 89 if (resource.labels().is_trashed()) { 90 details->set_missing(true); 91 return file.Pass(); 92 } 93 94 PopulateFileDetailsByFileResource(resource, details); 95 return file.Pass(); 96} 97 98scoped_ptr<FileMetadata> CreateFileMetadataFromChangeResource( 99 const google_apis::ChangeResource& change) { 100 scoped_ptr<FileMetadata> file(new FileMetadata); 101 file->set_file_id(change.file_id()); 102 103 FileDetails* details = file->mutable_details(); 104 details->set_change_id(change.change_id()); 105 106 if (change.is_deleted()) { 107 details->set_missing(true); 108 return file.Pass(); 109 } 110 111 PopulateFileDetailsByFileResource(*change.file(), details); 112 return file.Pass(); 113} 114 115webkit_blob::ScopedFile CreateTemporaryFile() { 116 base::FilePath temp_file_path; 117 if (!file_util::CreateTemporaryFile(&temp_file_path)) 118 return webkit_blob::ScopedFile(); 119 120 return webkit_blob::ScopedFile( 121 temp_file_path, 122 webkit_blob::ScopedFile::DELETE_ON_SCOPE_OUT, 123 base::MessageLoopProxy::current().get()); 124} 125 126std::string FileKindToString(FileKind file_kind) { 127 switch (file_kind) { 128 case FILE_KIND_UNSUPPORTED: 129 return "unsupported"; 130 case FILE_KIND_FILE: 131 return "file"; 132 case FILE_KIND_FOLDER: 133 return "folder"; 134 } 135 136 NOTREACHED(); 137 return "unknown"; 138} 139 140bool HasFileAsParent(const FileDetails& details, const std::string& file_id) { 141 for (int i = 0; i < details.parent_folder_ids_size(); ++i) { 142 if (details.parent_folder_ids(i) == file_id) 143 return true; 144 } 145 return false; 146} 147 148std::string GetMimeTypeFromTitle(const base::FilePath& title) { 149 base::FilePath::StringType extension = title.Extension(); 150 std::string mime_type; 151 if (extension.empty() || 152 !net::GetWellKnownMimeTypeFromExtension(extension.substr(1), &mime_type)) 153 return kMimeTypeOctetStream; 154 return mime_type; 155} 156 157scoped_ptr<google_apis::ResourceEntry> GetOldestCreatedFolderResource( 158 ScopedVector<google_apis::ResourceEntry> candidates) { 159 scoped_ptr<google_apis::ResourceEntry> oldest; 160 for (size_t i = 0; i < candidates.size(); ++i) { 161 google_apis::ResourceEntry* entry = candidates[i]; 162 if (!entry->is_folder()) 163 continue; 164 165 if (!oldest || oldest->published_time() > entry->published_time()) { 166 oldest.reset(entry); 167 candidates[i] = NULL; 168 } 169 } 170 171 return oldest.Pass(); 172} 173 174} // namespace drive_backend 175} // namespace sync_file_system 176