drive_api_parser.cc 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819
  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. #include "google_apis/drive/drive_api_parser.h"
  5. #include <stddef.h>
  6. #include <memory>
  7. #include "base/json/json_value_converter.h"
  8. #include "base/strings/string_number_conversions.h"
  9. #include "base/strings/string_piece.h"
  10. #include "base/strings/string_util.h"
  11. #include "base/values.h"
  12. #include "google_apis/common/parser_util.h"
  13. #include "google_apis/common/time_util.h"
  14. namespace google_apis {
  15. namespace {
  16. const int64_t kUnsetFileSize = -1;
  17. bool CreateFileResourceFromValue(const base::Value* value,
  18. std::unique_ptr<FileResource>* file) {
  19. *file = FileResource::CreateFrom(*value);
  20. return !!*file;
  21. }
  22. bool CreateTeamDriveResourceFromValue(
  23. const base::Value* value,
  24. std::unique_ptr<TeamDriveResource>* file) {
  25. *file = TeamDriveResource::CreateFrom(*value);
  26. return !!*file;
  27. }
  28. // Converts |url_string| to |result|. Always returns true to be used
  29. // for JSONValueConverter::RegisterCustomField method.
  30. // TODO(mukai): make it return false in case of invalid |url_string|.
  31. bool GetGURLFromString(base::StringPiece url_string, GURL* result) {
  32. *result = GURL(url_string);
  33. return true;
  34. }
  35. // Converts |value| to |result|.
  36. bool GetParentsFromValue(const base::Value* value,
  37. std::vector<ParentReference>* result) {
  38. DCHECK(value);
  39. DCHECK(result);
  40. if (!value->is_list())
  41. return false;
  42. base::JSONValueConverter<ParentReference> converter;
  43. result->resize(value->GetListDeprecated().size());
  44. for (size_t i = 0; i < value->GetListDeprecated().size(); ++i) {
  45. const base::Value& parent_value = value->GetListDeprecated()[i];
  46. if (!converter.Convert(parent_value, &(*result)[i]))
  47. return false;
  48. }
  49. return true;
  50. }
  51. // Converts |value| to |result|. The key of |value| is app_id, and its value
  52. // is URL to open the resource on the web app.
  53. bool GetOpenWithLinksFromDictionaryValue(
  54. const base::Value* value,
  55. std::vector<FileResource::OpenWithLink>* result) {
  56. DCHECK(value);
  57. DCHECK(result);
  58. const base::DictionaryValue* dictionary_value;
  59. if (!value->GetAsDictionary(&dictionary_value))
  60. return false;
  61. result->reserve(dictionary_value->DictSize());
  62. for (base::DictionaryValue::Iterator iter(*dictionary_value); !iter.IsAtEnd();
  63. iter.Advance()) {
  64. const std::string* string_value = iter.value().GetIfString();
  65. if (!string_value)
  66. return false;
  67. FileResource::OpenWithLink open_with_link;
  68. open_with_link.app_id = iter.key();
  69. open_with_link.open_url = GURL(*string_value);
  70. result->push_back(open_with_link);
  71. }
  72. return true;
  73. }
  74. // Drive v2 API JSON names.
  75. // Definition order follows the order of documentation in
  76. // https://developers.google.com/drive/v2/reference/
  77. // Common
  78. const char kLargestChangeId[] = "largestChangeId";
  79. const char kNextPageToken[] = "nextPageToken";
  80. // About Resource
  81. // https://developers.google.com/drive/v2/reference/about
  82. const char kAboutKind[] = "drive#about";
  83. const char kQuotaBytesTotal[] = "quotaBytesTotal";
  84. const char kQuotaBytesUsedAggregate[] = "quotaBytesUsedAggregate";
  85. const char kRootFolderId[] = "rootFolderId";
  86. // Parent Resource
  87. // https://developers.google.com/drive/v2/reference/parents
  88. const char kParentReferenceKind[] = "drive#parentReference";
  89. // File Resource
  90. // https://developers.google.com/drive/v2/reference/files
  91. const char kFileKind[] = "drive#file";
  92. const char kTitle[] = "title";
  93. const char kMimeType[] = "mimeType";
  94. const char kCreatedDate[] = "createdDate";
  95. const char kModificationDate[] = "modificationDate";
  96. const char kModifiedDate[] = "modifiedDate";
  97. const char kModifiedByMeDate[] = "modifiedByMeDate";
  98. const char kLastViewedByMeDate[] = "lastViewedByMeDate";
  99. const char kSharedWithMeDate[] = "sharedWithMeDate";
  100. const char kMd5Checksum[] = "md5Checksum";
  101. const char kFileSize[] = "fileSize";
  102. const char kAlternateLink[] = "alternateLink";
  103. const char kParents[] = "parents";
  104. const char kOpenWithLinks[] = "openWithLinks";
  105. const char kLabels[] = "labels";
  106. const char kImageMediaMetadata[] = "imageMediaMetadata";
  107. const char kShared[] = "shared";
  108. // These 5 flags are defined under |labels|.
  109. const char kLabelTrashed[] = "trashed";
  110. const char kLabelStarred[] = "starred";
  111. // These 3 flags are defined under |imageMediaMetadata|.
  112. const char kImageMediaMetadataWidth[] = "width";
  113. const char kImageMediaMetadataHeight[] = "height";
  114. const char kImageMediaMetadataRotation[] = "rotation";
  115. // URL to the share dialog UI, which is provided only in v2internal.
  116. const char kShareLink[] = "shareLink";
  117. const char kDriveFolderMimeType[] = "application/vnd.google-apps.folder";
  118. // Team Drive
  119. const char kTeamDriveKind[] = "drive#teamDrive";
  120. const char kTeamDriveListKind[] = "drive#teamDriveList";
  121. const char kCapabilities[] = "capabilities";
  122. // Team Drive capabilities.
  123. // See "capabilities" in
  124. // https://developers.google.com/drive/v2/reference/teamdrives#resource.
  125. const char kCanAddChildren[] = "canAddChildren";
  126. const char kCanComment[] = "canComment";
  127. const char kCanCopy[] = "canCopy";
  128. const char kCanDeleteTeamDrive[] = "canDeleteTeamDrive";
  129. const char kCanDownload[] = "canDownload";
  130. const char kCanEdit[] = "canEdit";
  131. const char kCanListChildren[] = "canListChildren";
  132. const char kCanManageMembers[] = "canManageMembers";
  133. const char kCanReadRevisions[] = "canReadRevisions";
  134. const char kCanRemoveChildren[] = "canRemoveChildren";
  135. const char kCanRename[] = "canRename";
  136. const char kCanRenameTeamDrive[] = "canRenameTeamDrive";
  137. const char kCanShare[] = "canShare";
  138. // Files List
  139. // https://developers.google.com/drive/v2/reference/files/list
  140. const char kFileListKind[] = "drive#fileList";
  141. const char kNextLink[] = "nextLink";
  142. // File Resource capabilities.
  143. // See "capabilities" in
  144. // https://developers.google.com/drive/v2/reference/files#resource.
  145. const char kCanChangeRestrictedDownload[] = "canChangeRestrictedDownload";
  146. const char kCanDelete[] = "canDelete";
  147. const char kCanMoveItemIntoTeamDrive[] = "canMoveItemIntoTeamDrive";
  148. const char kCanMoveTeamDriveItem[] = "canMoveTeamDriveItem";
  149. const char kCanReadTeamDrive[] = "canReadTeamDrive";
  150. const char kCanTrash[] = "canTrash";
  151. const char kCanUntrash[] = "canUntrash";
  152. // Change Resource
  153. // https://developers.google.com/drive/v2/reference/changes
  154. const char kChangeKind[] = "drive#change";
  155. const char kType[] = "type";
  156. const char kFileId[] = "fileId";
  157. const char kDeleted[] = "deleted";
  158. const char kFile[] = "file";
  159. const char kTeamDrive[] = "teamDrive";
  160. const char kTeamDriveId[] = "teamDriveId";
  161. const char kStartPageToken[] = "startPageToken";
  162. const char kNewStartPageToken[] = "newStartPageToken";
  163. // Changes List
  164. // https://developers.google.com/drive/v2/reference/changes/list
  165. const char kChangeListKind[] = "drive#changeList";
  166. // Maps category name to enum ChangeType.
  167. struct ChangeTypeMap {
  168. ChangeResource::ChangeType type;
  169. const char* type_name;
  170. };
  171. constexpr ChangeTypeMap kChangeTypeMap[] = {
  172. {ChangeResource::FILE, "file"},
  173. {ChangeResource::TEAM_DRIVE, "teamDrive"},
  174. };
  175. } // namespace
  176. ////////////////////////////////////////////////////////////////////////////////
  177. // AboutResource implementation
  178. AboutResource::AboutResource()
  179. : largest_change_id_(0),
  180. quota_bytes_total_(0),
  181. quota_bytes_used_aggregate_(0) {}
  182. AboutResource::~AboutResource() {}
  183. // static
  184. std::unique_ptr<AboutResource> AboutResource::CreateFrom(
  185. const base::Value& value) {
  186. std::unique_ptr<AboutResource> resource(new AboutResource());
  187. if (!IsResourceKindExpected(value, kAboutKind) || !resource->Parse(value)) {
  188. LOG(ERROR) << "Unable to create: Invalid About resource JSON!";
  189. return nullptr;
  190. }
  191. return resource;
  192. }
  193. // static
  194. void AboutResource::RegisterJSONConverter(
  195. base::JSONValueConverter<AboutResource>* converter) {
  196. converter->RegisterCustomField<int64_t>(kLargestChangeId,
  197. &AboutResource::largest_change_id_,
  198. &base::StringToInt64);
  199. converter->RegisterCustomField<int64_t>(kQuotaBytesTotal,
  200. &AboutResource::quota_bytes_total_,
  201. &base::StringToInt64);
  202. converter->RegisterCustomField<int64_t>(
  203. kQuotaBytesUsedAggregate, &AboutResource::quota_bytes_used_aggregate_,
  204. &base::StringToInt64);
  205. converter->RegisterStringField(kRootFolderId,
  206. &AboutResource::root_folder_id_);
  207. }
  208. bool AboutResource::Parse(const base::Value& value) {
  209. base::JSONValueConverter<AboutResource> converter;
  210. if (!converter.Convert(value, this)) {
  211. LOG(ERROR) << "Unable to parse: Invalid About resource JSON!";
  212. return false;
  213. }
  214. return true;
  215. }
  216. ////////////////////////////////////////////////////////////////////////////////
  217. // TeamDriveCapabilities implementation
  218. TeamDriveCapabilities::TeamDriveCapabilities()
  219. : can_add_children_(false),
  220. can_comment_(false),
  221. can_copy_(false),
  222. can_delete_team_drive_(false),
  223. can_download_(false),
  224. can_edit_(false),
  225. can_list_children_(false),
  226. can_manage_members_(false),
  227. can_read_revisions_(false),
  228. can_remove_children_(false),
  229. can_rename_(false),
  230. can_rename_team_drive_(false),
  231. can_share_(false) {}
  232. TeamDriveCapabilities::TeamDriveCapabilities(const TeamDriveCapabilities& src) =
  233. default;
  234. TeamDriveCapabilities::~TeamDriveCapabilities() = default;
  235. // static
  236. void TeamDriveCapabilities::RegisterJSONConverter(
  237. base::JSONValueConverter<TeamDriveCapabilities>* converter) {
  238. converter->RegisterBoolField(kCanAddChildren,
  239. &TeamDriveCapabilities::can_add_children_);
  240. converter->RegisterBoolField(kCanComment,
  241. &TeamDriveCapabilities::can_comment_);
  242. converter->RegisterBoolField(kCanCopy, &TeamDriveCapabilities::can_copy_);
  243. converter->RegisterBoolField(kCanDeleteTeamDrive,
  244. &TeamDriveCapabilities::can_delete_team_drive_);
  245. converter->RegisterBoolField(kCanDownload,
  246. &TeamDriveCapabilities::can_download_);
  247. converter->RegisterBoolField(kCanEdit, &TeamDriveCapabilities::can_edit_);
  248. converter->RegisterBoolField(kCanListChildren,
  249. &TeamDriveCapabilities::can_list_children_);
  250. converter->RegisterBoolField(kCanManageMembers,
  251. &TeamDriveCapabilities::can_manage_members_);
  252. converter->RegisterBoolField(kCanReadRevisions,
  253. &TeamDriveCapabilities::can_read_revisions_);
  254. converter->RegisterBoolField(kCanRemoveChildren,
  255. &TeamDriveCapabilities::can_remove_children_);
  256. converter->RegisterBoolField(kCanRename, &TeamDriveCapabilities::can_rename_);
  257. converter->RegisterBoolField(kCanRenameTeamDrive,
  258. &TeamDriveCapabilities::can_rename_team_drive_);
  259. converter->RegisterBoolField(kCanShare, &TeamDriveCapabilities::can_share_);
  260. }
  261. ////////////////////////////////////////////////////////////////////////////////
  262. // TeamDriveResource implementation
  263. TeamDriveResource::TeamDriveResource() {}
  264. TeamDriveResource::~TeamDriveResource() {}
  265. // static
  266. std::unique_ptr<TeamDriveResource> TeamDriveResource::CreateFrom(
  267. const base::Value& value) {
  268. std::unique_ptr<TeamDriveResource> resource(new TeamDriveResource());
  269. if (!IsResourceKindExpected(value, kTeamDriveKind) ||
  270. !resource->Parse(value)) {
  271. LOG(ERROR) << "Unable to create: Invalid Team Drive resource JSON!";
  272. return nullptr;
  273. }
  274. return resource;
  275. }
  276. // static
  277. void TeamDriveResource::RegisterJSONConverter(
  278. base::JSONValueConverter<TeamDriveResource>* converter) {
  279. converter->RegisterStringField(kApiResponseIdKey, &TeamDriveResource::id_);
  280. converter->RegisterStringField(kApiResponseNameKey,
  281. &TeamDriveResource::name_);
  282. converter->RegisterNestedField(kCapabilities,
  283. &TeamDriveResource::capabilities_);
  284. }
  285. bool TeamDriveResource::Parse(const base::Value& value) {
  286. base::JSONValueConverter<TeamDriveResource> converter;
  287. if (!converter.Convert(value, this)) {
  288. LOG(ERROR) << "Unable to parse: Invalid Team Drive resource JSON!";
  289. return false;
  290. }
  291. return true;
  292. }
  293. ////////////////////////////////////////////////////////////////////////////////
  294. // TeamDriveList implementation
  295. TeamDriveList::TeamDriveList() {}
  296. TeamDriveList::~TeamDriveList() {}
  297. // static
  298. void TeamDriveList::RegisterJSONConverter(
  299. base::JSONValueConverter<TeamDriveList>* converter) {
  300. converter->RegisterStringField(kNextPageToken,
  301. &TeamDriveList::next_page_token_);
  302. converter->RegisterRepeatedMessage<TeamDriveResource>(kApiResponseItemsKey,
  303. &TeamDriveList::items_);
  304. }
  305. // static
  306. bool TeamDriveList::HasTeamDriveListKind(const base::Value& value) {
  307. return IsResourceKindExpected(value, kTeamDriveListKind);
  308. }
  309. // static
  310. std::unique_ptr<TeamDriveList> TeamDriveList::CreateFrom(
  311. const base::Value& value) {
  312. std::unique_ptr<TeamDriveList> resource(new TeamDriveList());
  313. if (!HasTeamDriveListKind(value) || !resource->Parse(value)) {
  314. LOG(ERROR) << "Unable to create: Invalid TeamDriveList JSON!";
  315. return nullptr;
  316. }
  317. return resource;
  318. }
  319. bool TeamDriveList::Parse(const base::Value& value) {
  320. base::JSONValueConverter<TeamDriveList> converter;
  321. if (!converter.Convert(value, this)) {
  322. LOG(ERROR) << "Unable to parse: Invalid TeamDriveList";
  323. return false;
  324. }
  325. return true;
  326. }
  327. ////////////////////////////////////////////////////////////////////////////////
  328. // ParentReference implementation
  329. ParentReference::ParentReference() {}
  330. ParentReference::~ParentReference() {}
  331. // static
  332. void ParentReference::RegisterJSONConverter(
  333. base::JSONValueConverter<ParentReference>* converter) {
  334. converter->RegisterStringField(kApiResponseIdKey, &ParentReference::file_id_);
  335. }
  336. // static
  337. std::unique_ptr<ParentReference> ParentReference::CreateFrom(
  338. const base::Value& value) {
  339. std::unique_ptr<ParentReference> reference(new ParentReference());
  340. if (!IsResourceKindExpected(value, kParentReferenceKind) ||
  341. !reference->Parse(value)) {
  342. LOG(ERROR) << "Unable to create: Invalid ParentRefernce JSON!";
  343. return nullptr;
  344. }
  345. return reference;
  346. }
  347. bool ParentReference::Parse(const base::Value& value) {
  348. base::JSONValueConverter<ParentReference> converter;
  349. if (!converter.Convert(value, this)) {
  350. LOG(ERROR) << "Unable to parse: Invalid ParentReference";
  351. return false;
  352. }
  353. return true;
  354. }
  355. ////////////////////////////////////////////////////////////////////////////////
  356. // FileResourceCapabilities implementation
  357. FileResourceCapabilities::FileResourceCapabilities()
  358. : can_add_children_(false),
  359. can_change_restricted_download_(false),
  360. can_comment_(false),
  361. can_copy_(false),
  362. can_delete_(false),
  363. can_download_(false),
  364. can_edit_(false),
  365. can_list_children_(false),
  366. can_move_item_into_team_drive_(false),
  367. can_move_team_drive_item_(false),
  368. can_read_revisions_(false),
  369. can_read_team_drive_(false),
  370. can_remove_children_(false),
  371. can_rename_(false),
  372. can_share_(false),
  373. can_trash_(false),
  374. can_untrash_(false) {}
  375. FileResourceCapabilities::FileResourceCapabilities(
  376. const FileResourceCapabilities& src) = default;
  377. FileResourceCapabilities::~FileResourceCapabilities() {}
  378. // static
  379. void FileResourceCapabilities::RegisterJSONConverter(
  380. base::JSONValueConverter<FileResourceCapabilities>* converter) {
  381. converter->RegisterBoolField(kCanAddChildren,
  382. &FileResourceCapabilities::can_add_children_);
  383. converter->RegisterBoolField(
  384. kCanChangeRestrictedDownload,
  385. &FileResourceCapabilities::can_change_restricted_download_);
  386. converter->RegisterBoolField(kCanComment,
  387. &FileResourceCapabilities::can_comment_);
  388. converter->RegisterBoolField(kCanCopy, &FileResourceCapabilities::can_copy_);
  389. converter->RegisterBoolField(kCanDelete,
  390. &FileResourceCapabilities::can_delete_);
  391. converter->RegisterBoolField(kCanDownload,
  392. &FileResourceCapabilities::can_download_);
  393. converter->RegisterBoolField(kCanEdit, &FileResourceCapabilities::can_edit_);
  394. converter->RegisterBoolField(kCanListChildren,
  395. &FileResourceCapabilities::can_list_children_);
  396. converter->RegisterBoolField(
  397. kCanMoveItemIntoTeamDrive,
  398. &FileResourceCapabilities::can_move_item_into_team_drive_);
  399. converter->RegisterBoolField(
  400. kCanMoveTeamDriveItem,
  401. &FileResourceCapabilities::can_move_team_drive_item_);
  402. converter->RegisterBoolField(kCanReadRevisions,
  403. &FileResourceCapabilities::can_read_revisions_);
  404. converter->RegisterBoolField(kCanReadTeamDrive,
  405. &FileResourceCapabilities::can_read_team_drive_);
  406. converter->RegisterBoolField(kCanRemoveChildren,
  407. &FileResourceCapabilities::can_remove_children_);
  408. converter->RegisterBoolField(kCanRename,
  409. &FileResourceCapabilities::can_rename_);
  410. converter->RegisterBoolField(kCanShare,
  411. &FileResourceCapabilities::can_share_);
  412. converter->RegisterBoolField(kCanTrash,
  413. &FileResourceCapabilities::can_trash_);
  414. converter->RegisterBoolField(kCanUntrash,
  415. &FileResourceCapabilities::can_untrash_);
  416. }
  417. ////////////////////////////////////////////////////////////////////////////////
  418. // FileResource implementation
  419. FileResource::FileResource() : shared_(false), file_size_(kUnsetFileSize) {}
  420. FileResource::FileResource(const FileResource& other) = default;
  421. FileResource::~FileResource() {}
  422. // static
  423. void FileResource::RegisterJSONConverter(
  424. base::JSONValueConverter<FileResource>* converter) {
  425. converter->RegisterStringField(kApiResponseIdKey, &FileResource::file_id_);
  426. converter->RegisterStringField(kApiResponseETagKey, &FileResource::etag_);
  427. converter->RegisterStringField(kTitle, &FileResource::title_);
  428. converter->RegisterStringField(kMimeType, &FileResource::mime_type_);
  429. converter->RegisterNestedField(kLabels, &FileResource::labels_);
  430. converter->RegisterNestedField(kImageMediaMetadata,
  431. &FileResource::image_media_metadata_);
  432. converter->RegisterNestedField(kCapabilities, &FileResource::capabilities_);
  433. converter->RegisterCustomField<base::Time>(
  434. kCreatedDate, &FileResource::created_date_, &util::GetTimeFromString);
  435. converter->RegisterCustomField<base::Time>(
  436. kModifiedDate, &FileResource::modified_date_, &util::GetTimeFromString);
  437. converter->RegisterCustomField<base::Time>(
  438. kModifiedByMeDate, &FileResource::modified_by_me_date_,
  439. &util::GetTimeFromString);
  440. converter->RegisterCustomField<base::Time>(
  441. kLastViewedByMeDate, &FileResource::last_viewed_by_me_date_,
  442. &util::GetTimeFromString);
  443. converter->RegisterCustomField<base::Time>(
  444. kSharedWithMeDate, &FileResource::shared_with_me_date_,
  445. &util::GetTimeFromString);
  446. converter->RegisterBoolField(kShared, &FileResource::shared_);
  447. converter->RegisterStringField(kMd5Checksum, &FileResource::md5_checksum_);
  448. converter->RegisterCustomField<int64_t>(kFileSize, &FileResource::file_size_,
  449. &base::StringToInt64);
  450. converter->RegisterCustomField<GURL>(
  451. kAlternateLink, &FileResource::alternate_link_, GetGURLFromString);
  452. converter->RegisterCustomField<GURL>(kShareLink, &FileResource::share_link_,
  453. GetGURLFromString);
  454. converter->RegisterCustomValueField<std::vector<ParentReference>>(
  455. kParents, &FileResource::parents_, GetParentsFromValue);
  456. converter->RegisterCustomValueField<std::vector<OpenWithLink>>(
  457. kOpenWithLinks, &FileResource::open_with_links_,
  458. GetOpenWithLinksFromDictionaryValue);
  459. converter->RegisterStringField(kTeamDriveId, &FileResource::team_drive_id_);
  460. }
  461. // static
  462. std::unique_ptr<FileResource> FileResource::CreateFrom(
  463. const base::Value& value) {
  464. std::unique_ptr<FileResource> resource(new FileResource());
  465. if (!IsResourceKindExpected(value, kFileKind) || !resource->Parse(value)) {
  466. LOG(ERROR) << "Unable to create: Invalid FileResource JSON!";
  467. return nullptr;
  468. }
  469. return resource;
  470. }
  471. bool FileResource::IsDirectory() const {
  472. return mime_type_ == kDriveFolderMimeType;
  473. }
  474. bool FileResource::IsHostedDocument() const {
  475. // Hosted documents don't have fileSize field set:
  476. // https://developers.google.com/drive/v2/reference/files
  477. return !IsDirectory() && file_size_ == kUnsetFileSize;
  478. }
  479. bool FileResource::Parse(const base::Value& value) {
  480. base::JSONValueConverter<FileResource> converter;
  481. if (!converter.Convert(value, this)) {
  482. LOG(ERROR) << "Unable to parse: Invalid FileResource";
  483. return false;
  484. }
  485. return true;
  486. }
  487. ////////////////////////////////////////////////////////////////////////////////
  488. // FileList implementation
  489. FileList::FileList() {}
  490. FileList::~FileList() {}
  491. // static
  492. void FileList::RegisterJSONConverter(
  493. base::JSONValueConverter<FileList>* converter) {
  494. converter->RegisterCustomField<GURL>(kNextLink, &FileList::next_link_,
  495. GetGURLFromString);
  496. converter->RegisterRepeatedMessage<FileResource>(kApiResponseItemsKey,
  497. &FileList::items_);
  498. }
  499. // static
  500. bool FileList::HasFileListKind(const base::Value& value) {
  501. return IsResourceKindExpected(value, kFileListKind);
  502. }
  503. // static
  504. std::unique_ptr<FileList> FileList::CreateFrom(const base::Value& value) {
  505. std::unique_ptr<FileList> resource(new FileList());
  506. if (!HasFileListKind(value) || !resource->Parse(value)) {
  507. LOG(ERROR) << "Unable to create: Invalid FileList JSON!";
  508. return nullptr;
  509. }
  510. return resource;
  511. }
  512. bool FileList::Parse(const base::Value& value) {
  513. base::JSONValueConverter<FileList> converter;
  514. if (!converter.Convert(value, this)) {
  515. LOG(ERROR) << "Unable to parse: Invalid FileList";
  516. return false;
  517. }
  518. return true;
  519. }
  520. ////////////////////////////////////////////////////////////////////////////////
  521. // ChangeResource implementation
  522. ChangeResource::ChangeResource()
  523. : change_id_(0), type_(UNKNOWN), deleted_(false) {}
  524. ChangeResource::~ChangeResource() {}
  525. // static
  526. void ChangeResource::RegisterJSONConverter(
  527. base::JSONValueConverter<ChangeResource>* converter) {
  528. converter->RegisterCustomField<int64_t>(
  529. kApiResponseIdKey, &ChangeResource::change_id_, &base::StringToInt64);
  530. converter->RegisterCustomField<ChangeType>(kType, &ChangeResource::type_,
  531. &ChangeResource::GetType);
  532. converter->RegisterStringField(kFileId, &ChangeResource::file_id_);
  533. converter->RegisterBoolField(kDeleted, &ChangeResource::deleted_);
  534. converter->RegisterCustomValueField(kFile, &ChangeResource::file_,
  535. &CreateFileResourceFromValue);
  536. converter->RegisterCustomField<base::Time>(
  537. kModificationDate, &ChangeResource::modification_date_,
  538. &util::GetTimeFromString);
  539. converter->RegisterStringField(kTeamDriveId, &ChangeResource::team_drive_id_);
  540. converter->RegisterCustomValueField(kTeamDrive, &ChangeResource::team_drive_,
  541. &CreateTeamDriveResourceFromValue);
  542. }
  543. // static
  544. std::unique_ptr<ChangeResource> ChangeResource::CreateFrom(
  545. const base::Value& value) {
  546. std::unique_ptr<ChangeResource> resource(new ChangeResource());
  547. if (!IsResourceKindExpected(value, kChangeKind) || !resource->Parse(value)) {
  548. LOG(ERROR) << "Unable to create: Invalid ChangeResource JSON!";
  549. return nullptr;
  550. }
  551. return resource;
  552. }
  553. bool ChangeResource::Parse(const base::Value& value) {
  554. base::JSONValueConverter<ChangeResource> converter;
  555. if (!converter.Convert(value, this)) {
  556. LOG(ERROR) << "Unable to parse: Invalid ChangeResource";
  557. return false;
  558. }
  559. return true;
  560. }
  561. // static
  562. bool ChangeResource::GetType(base::StringPiece type_name,
  563. ChangeResource::ChangeType* result) {
  564. for (size_t i = 0; i < std::size(kChangeTypeMap); i++) {
  565. if (type_name == kChangeTypeMap[i].type_name) {
  566. *result = kChangeTypeMap[i].type;
  567. return true;
  568. }
  569. }
  570. DVLOG(1) << "Unknown change type" << type_name;
  571. return false;
  572. }
  573. ////////////////////////////////////////////////////////////////////////////////
  574. // ChangeList implementation
  575. ChangeList::ChangeList() = default;
  576. ChangeList::~ChangeList() = default;
  577. // static
  578. void ChangeList::RegisterJSONConverter(
  579. base::JSONValueConverter<ChangeList>* converter) {
  580. converter->RegisterCustomField<GURL>(kNextLink, &ChangeList::next_link_,
  581. GetGURLFromString);
  582. converter->RegisterCustomField<int64_t>(
  583. kLargestChangeId, &ChangeList::largest_change_id_, &base::StringToInt64);
  584. converter->RegisterStringField(kNewStartPageToken,
  585. &ChangeList::new_start_page_token_);
  586. converter->RegisterRepeatedMessage<ChangeResource>(kApiResponseItemsKey,
  587. &ChangeList::items_);
  588. }
  589. // static
  590. bool ChangeList::HasChangeListKind(const base::Value& value) {
  591. return IsResourceKindExpected(value, kChangeListKind);
  592. }
  593. // static
  594. std::unique_ptr<ChangeList> ChangeList::CreateFrom(const base::Value& value) {
  595. std::unique_ptr<ChangeList> resource(new ChangeList());
  596. if (!HasChangeListKind(value) || !resource->Parse(value)) {
  597. LOG(ERROR) << "Unable to create: Invalid ChangeList JSON!";
  598. return nullptr;
  599. }
  600. return resource;
  601. }
  602. bool ChangeList::Parse(const base::Value& value) {
  603. base::JSONValueConverter<ChangeList> converter;
  604. if (!converter.Convert(value, this)) {
  605. LOG(ERROR) << "Unable to parse: Invalid ChangeList";
  606. return false;
  607. }
  608. return true;
  609. }
  610. ////////////////////////////////////////////////////////////////////////////////
  611. // FileLabels implementation
  612. FileLabels::FileLabels() : trashed_(false), starred_(false) {}
  613. FileLabels::~FileLabels() {}
  614. // static
  615. void FileLabels::RegisterJSONConverter(
  616. base::JSONValueConverter<FileLabels>* converter) {
  617. converter->RegisterBoolField(kLabelTrashed, &FileLabels::trashed_);
  618. converter->RegisterBoolField(kLabelStarred, &FileLabels::starred_);
  619. }
  620. // static
  621. std::unique_ptr<FileLabels> FileLabels::CreateFrom(const base::Value& value) {
  622. std::unique_ptr<FileLabels> resource(new FileLabels());
  623. if (!resource->Parse(value)) {
  624. LOG(ERROR) << "Unable to create: Invalid FileLabels JSON!";
  625. return nullptr;
  626. }
  627. return resource;
  628. }
  629. bool FileLabels::Parse(const base::Value& value) {
  630. base::JSONValueConverter<FileLabels> converter;
  631. if (!converter.Convert(value, this)) {
  632. LOG(ERROR) << "Unable to parse: Invalid FileLabels.";
  633. return false;
  634. }
  635. return true;
  636. }
  637. ////////////////////////////////////////////////////////////////////////////////
  638. // ImageMediaMetadata implementation
  639. ImageMediaMetadata::ImageMediaMetadata()
  640. : width_(-1), height_(-1), rotation_(-1) {}
  641. ImageMediaMetadata::~ImageMediaMetadata() {}
  642. // static
  643. void ImageMediaMetadata::RegisterJSONConverter(
  644. base::JSONValueConverter<ImageMediaMetadata>* converter) {
  645. converter->RegisterIntField(kImageMediaMetadataWidth,
  646. &ImageMediaMetadata::width_);
  647. converter->RegisterIntField(kImageMediaMetadataHeight,
  648. &ImageMediaMetadata::height_);
  649. converter->RegisterIntField(kImageMediaMetadataRotation,
  650. &ImageMediaMetadata::rotation_);
  651. }
  652. // static
  653. std::unique_ptr<ImageMediaMetadata> ImageMediaMetadata::CreateFrom(
  654. const base::Value& value) {
  655. std::unique_ptr<ImageMediaMetadata> resource(new ImageMediaMetadata());
  656. if (!resource->Parse(value)) {
  657. LOG(ERROR) << "Unable to create: Invalid ImageMediaMetadata JSON!";
  658. return nullptr;
  659. }
  660. return resource;
  661. }
  662. bool ImageMediaMetadata::Parse(const base::Value& value) {
  663. base::JSONValueConverter<ImageMediaMetadata> converter;
  664. if (!converter.Convert(value, this)) {
  665. LOG(ERROR) << "Unable to parse: Invalid ImageMediaMetadata.";
  666. return false;
  667. }
  668. return true;
  669. }
  670. ////////////////////////////////////////////////////////////////////////////////
  671. // StartPageToken implementation
  672. StartPageToken::StartPageToken() = default;
  673. StartPageToken::~StartPageToken() = default;
  674. // static
  675. void StartPageToken::RegisterJSONConverter(
  676. base::JSONValueConverter<StartPageToken>* converter) {
  677. converter->RegisterStringField(kStartPageToken,
  678. &StartPageToken::start_page_token_);
  679. }
  680. // static
  681. std::unique_ptr<StartPageToken> StartPageToken::CreateFrom(
  682. const base::Value& value) {
  683. std::unique_ptr<StartPageToken> result = std::make_unique<StartPageToken>();
  684. if (!result->Parse(value)) {
  685. LOG(ERROR) << "Unable to parse: Invalid StartPageToken JSON.";
  686. return nullptr;
  687. }
  688. return result;
  689. }
  690. bool StartPageToken::Parse(const base::Value& value) {
  691. base::JSONValueConverter<StartPageToken> converter;
  692. if (!converter.Convert(value, this)) {
  693. LOG(ERROR) << "Unable to parse: Invalid StartPageToken.";
  694. return false;
  695. }
  696. return true;
  697. }
  698. } // namespace google_apis