resource_entry_conversion.cc revision 7dbb3d5cf0c15f500944d211057644d6a2f37371
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/strings/string_util.h"
12#include "base/strings/utf_string_conversions.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#include "net/base/escape.h"
18#include "url/gurl.h"
19
20namespace drive {
21
22namespace {
23
24const char kSharedWithMeLabel[] = "shared-with-me";
25
26// Checks if |entry| has a label "shared-with-me", which is added to entries
27// shared with the user.
28bool HasSharedWithMeLabel(const google_apis::ResourceEntry& entry) {
29  std::vector<std::string>::const_iterator it =
30      std::find(entry.labels().begin(), entry.labels().end(),
31                kSharedWithMeLabel);
32  return it != entry.labels().end();
33}
34
35}  // namespace
36
37ResourceEntry ConvertToResourceEntry(
38    const google_apis::ResourceEntry& input) {
39  ResourceEntry output;
40
41  // For regular files, the 'filename' and 'title' attribute in the metadata
42  // may be different (e.g. due to rename). To be consistent with the web
43  // interface and other client to use the 'title' attribute, instead of
44  // 'filename', as the file name in the local snapshot.
45  output.set_title(input.title());
46  output.set_base_name(util::NormalizeFileName(output.title()));
47  output.set_resource_id(input.resource_id());
48
49  // Sets parent Resource ID. On drive.google.com, a file can have multiple
50  // parents or no parent, but we are forcing a tree-shaped structure (i.e. no
51  // multi-parent or zero-parent entries). Therefore the first found "parent" is
52  // used for the entry and if the entry has no parent, we assign a special ID
53  // which represents no-parent entries. Tracked in http://crbug.com/158904.
54  const google_apis::Link* parent_link =
55      input.GetLinkByType(google_apis::Link::LINK_PARENT);
56  if (parent_link) {
57    output.set_parent_resource_id(util::ExtractResourceIdFromUrl(
58        parent_link->href()));
59  }
60  // Apply mapping from an empty parent to the special dummy directory.
61  if (output.parent_resource_id().empty())
62    output.set_parent_resource_id(util::kDriveOtherDirSpecialResourceId);
63
64  output.set_deleted(input.deleted());
65  output.set_shared_with_me(HasSharedWithMeLabel(input));
66
67  PlatformFileInfoProto* file_info = output.mutable_file_info();
68
69  file_info->set_last_modified(input.updated_time().ToInternalValue());
70  // If the file has never been viewed (last_viewed_time().is_null() == true),
71  // then we will set the last_accessed field in the protocol buffer to 0.
72  file_info->set_last_accessed(input.last_viewed_time().ToInternalValue());
73  file_info->set_creation_time(input.published_time().ToInternalValue());
74
75  if (input.is_file() || input.is_hosted_document()) {
76    FileSpecificInfo* file_specific_info = output.mutable_file_specific_info();
77    if (input.is_file()) {
78      file_info->set_size(input.file_size());
79      file_specific_info->set_md5(input.file_md5());
80
81      // The resumable-edit-media link should only be present for regular
82      // files as hosted documents are not uploadable.
83    } else if (input.is_hosted_document()) {
84      // Attach .g<something> extension to hosted documents so we can special
85      // case their handling in UI.
86      // TODO(satorux): Figure out better way how to pass input info like kind
87      // to UI through the File API stack.
88      const std::string document_extension = input.GetHostedDocumentExtension();
89      file_specific_info->set_document_extension(document_extension);
90      output.set_base_name(
91          util::NormalizeFileName(output.title() + document_extension));
92
93      // We don't know the size of hosted docs and it does not matter since
94      // is has no effect on the quota.
95      file_info->set_size(0);
96    }
97    file_info->set_is_directory(false);
98    file_specific_info->set_content_mime_type(input.content_mime_type());
99    file_specific_info->set_is_hosted_document(input.is_hosted_document());
100
101    const google_apis::Link* thumbnail_link =
102        input.GetLinkByType(google_apis::Link::LINK_THUMBNAIL);
103    if (thumbnail_link)
104      file_specific_info->set_thumbnail_url(thumbnail_link->href().spec());
105
106    const google_apis::Link* alternate_link =
107        input.GetLinkByType(google_apis::Link::LINK_ALTERNATE);
108    if (alternate_link)
109      file_specific_info->set_alternate_url(alternate_link->href().spec());
110
111    const google_apis::Link* share_link =
112        input.GetLinkByType(google_apis::Link::LINK_SHARE);
113    if (share_link)
114      file_specific_info->set_share_url(share_link->href().spec());
115  } else if (input.is_folder()) {
116    file_info->set_is_directory(true);
117  } else {
118    // Some resource entries don't map into files (i.e. sites).
119    return ResourceEntry();
120  }
121
122  return output;
123}
124
125}  // namespace drive
126