resource_entry_conversion.cc revision a36e5920737c6adbddd3e43b760e5de8431db6e0
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#include "chrome/browser/chromeos/drive/resource_entry_conversion.h" 6 7#include <algorithm> 8#include <string> 9 10#include "base/logging.h" 11#include "base/platform_file.h" 12#include "base/time/time.h" 13#include "chrome/browser/chromeos/drive/drive.pb.h" 14#include "chrome/browser/chromeos/drive/file_system_util.h" 15#include "chrome/browser/drive/drive_api_util.h" 16#include "chrome/browser/google_apis/gdata_wapi_parser.h" 17 18namespace drive { 19 20namespace { 21 22const char kSharedWithMeLabel[] = "shared-with-me"; 23 24// Checks if |entry| has a label "shared-with-me", which is added to entries 25// shared with the user. 26bool HasSharedWithMeLabel(const google_apis::ResourceEntry& entry) { 27 std::vector<std::string>::const_iterator it = 28 std::find(entry.labels().begin(), entry.labels().end(), 29 kSharedWithMeLabel); 30 return it != entry.labels().end(); 31} 32 33} // namespace 34 35bool ConvertToResourceEntry(const google_apis::ResourceEntry& input, 36 ResourceEntry* output) { 37 DCHECK(output); 38 39 // For regular files, the 'filename' and 'title' attribute in the metadata 40 // may be different (e.g. due to rename). To be consistent with the web 41 // interface and other client to use the 'title' attribute, instead of 42 // 'filename', as the file name in the local snapshot. 43 output->set_title(input.title()); 44 output->set_base_name(util::NormalizeFileName(output->title())); 45 output->set_resource_id(input.resource_id()); 46 47 // Sets parent Resource ID. On drive.google.com, a file can have multiple 48 // parents or no parent, but we are forcing a tree-shaped structure (i.e. no 49 // multi-parent or zero-parent entries). Therefore the first found "parent" is 50 // used for the entry and if the entry has no parent, we assign a special ID 51 // which represents no-parent entries. Tracked in http://crbug.com/158904. 52 const google_apis::Link* parent_link = 53 input.GetLinkByType(google_apis::Link::LINK_PARENT); 54 if (parent_link) { 55 output->set_parent_resource_id(util::ExtractResourceIdFromUrl( 56 parent_link->href())); 57 } 58 // Apply mapping from an empty parent to the special dummy directory. 59 if (output->parent_resource_id().empty()) 60 output->set_parent_resource_id(util::kDriveOtherDirSpecialResourceId); 61 62 output->set_deleted(input.deleted()); 63 output->set_shared_with_me(HasSharedWithMeLabel(input)); 64 65 PlatformFileInfoProto* file_info = output->mutable_file_info(); 66 67 file_info->set_last_modified(input.updated_time().ToInternalValue()); 68 // If the file has never been viewed (last_viewed_time().is_null() == true), 69 // then we will set the last_accessed field in the protocol buffer to 0. 70 file_info->set_last_accessed(input.last_viewed_time().ToInternalValue()); 71 file_info->set_creation_time(input.published_time().ToInternalValue()); 72 73 if (input.is_file() || input.is_hosted_document()) { 74 FileSpecificInfo* file_specific_info = output->mutable_file_specific_info(); 75 if (input.is_file()) { 76 file_info->set_size(input.file_size()); 77 file_specific_info->set_md5(input.file_md5()); 78 79 // The resumable-edit-media link should only be present for regular 80 // files as hosted documents are not uploadable. 81 } else if (input.is_hosted_document()) { 82 // Attach .g<something> extension to hosted documents so we can special 83 // case their handling in UI. 84 // TODO(satorux): Figure out better way how to pass input info like kind 85 // to UI through the File API stack. 86 const std::string document_extension = input.GetHostedDocumentExtension(); 87 file_specific_info->set_document_extension(document_extension); 88 output->set_base_name( 89 util::NormalizeFileName(output->title() + document_extension)); 90 91 // We don't know the size of hosted docs and it does not matter since 92 // is has no effect on the quota. 93 file_info->set_size(0); 94 } 95 file_info->set_is_directory(false); 96 file_specific_info->set_content_mime_type(input.content_mime_type()); 97 file_specific_info->set_is_hosted_document(input.is_hosted_document()); 98 99 const google_apis::Link* thumbnail_link = 100 input.GetLinkByType(google_apis::Link::LINK_THUMBNAIL); 101 if (thumbnail_link) 102 file_specific_info->set_thumbnail_url(thumbnail_link->href().spec()); 103 104 const google_apis::Link* alternate_link = 105 input.GetLinkByType(google_apis::Link::LINK_ALTERNATE); 106 if (alternate_link) 107 file_specific_info->set_alternate_url(alternate_link->href().spec()); 108 } else if (input.is_folder()) { 109 file_info->set_is_directory(true); 110 } else { 111 // There are two cases to reach here. 112 // * The entry is something that doesn't map into files (i.e. sites). 113 // We don't handle these kind of entries hence return false. 114 // * The entry is un-shared to you by other owner. In that case, we 115 // get an entry with only deleted() and resource_id() fields are 116 // filled. Since we want to delete such entries locally as well, 117 // in that case we need to return true to proceed. 118 return input.deleted(); 119 } 120 121 return true; 122} 123 124void ConvertResourceEntryToPlatformFileInfo(const ResourceEntry& entry, 125 base::PlatformFileInfo* file_info) { 126 file_info->size = entry.file_info().size(); 127 file_info->is_directory = entry.file_info().is_directory(); 128 file_info->is_symbolic_link = entry.file_info().is_symbolic_link(); 129 file_info->last_modified = base::Time::FromInternalValue( 130 entry.file_info().last_modified()); 131 file_info->last_accessed = base::Time::FromInternalValue( 132 entry.file_info().last_accessed()); 133 file_info->creation_time = base::Time::FromInternalValue( 134 entry.file_info().creation_time()); 135} 136 137void SetPlatformFileInfoToResourceEntry(const base::PlatformFileInfo& file_info, 138 ResourceEntry* entry) { 139 PlatformFileInfoProto* entry_file_info = entry->mutable_file_info(); 140 entry_file_info->set_size(file_info.size); 141 entry_file_info->set_is_directory(file_info.is_directory); 142 entry_file_info->set_is_symbolic_link(file_info.is_symbolic_link); 143 entry_file_info->set_last_modified(file_info.last_modified.ToInternalValue()); 144 entry_file_info->set_last_accessed(file_info.last_accessed.ToInternalValue()); 145 entry_file_info->set_creation_time(file_info.creation_time.ToInternalValue()); 146} 147 148} // namespace drive 149