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#ifndef GOOGLE_APIS_DRIVE_DRIVE_API_PARSER_H_
6#define GOOGLE_APIS_DRIVE_DRIVE_API_PARSER_H_
7
8#include <string>
9
10#include "base/compiler_specific.h"
11#include "base/gtest_prod_util.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/memory/scoped_vector.h"
14#include "base/strings/string_piece.h"
15#include "base/time/time.h"
16#include "url/gurl.h"
17
18namespace base {
19class Value;
20template <class StructType>
21class JSONValueConverter;
22
23namespace internal {
24template <class NestedType>
25class RepeatedMessageConverter;
26}  // namespace internal
27}  // namespace base
28
29namespace google_apis {
30
31// About resource represents the account information about the current user.
32// https://developers.google.com/drive/v2/reference/about
33class AboutResource {
34 public:
35  AboutResource();
36  ~AboutResource();
37
38  // Registers the mapping between JSON field names and the members in this
39  // class.
40  static void RegisterJSONConverter(
41      base::JSONValueConverter<AboutResource>* converter);
42
43  // Creates about resource from parsed JSON.
44  static scoped_ptr<AboutResource> CreateFrom(const base::Value& value);
45
46  // Returns the largest change ID number.
47  int64 largest_change_id() const { return largest_change_id_; }
48  // Returns total number of quota bytes.
49  int64 quota_bytes_total() const { return quota_bytes_total_; }
50  // Returns the number of quota bytes used.
51  int64 quota_bytes_used() const { return quota_bytes_used_; }
52  // Returns root folder ID.
53  const std::string& root_folder_id() const { return root_folder_id_; }
54
55  void set_largest_change_id(int64 largest_change_id) {
56    largest_change_id_ = largest_change_id;
57  }
58  void set_quota_bytes_total(int64 quota_bytes_total) {
59    quota_bytes_total_ = quota_bytes_total;
60  }
61  void set_quota_bytes_used(int64 quota_bytes_used) {
62    quota_bytes_used_ = quota_bytes_used;
63  }
64  void set_root_folder_id(const std::string& root_folder_id) {
65    root_folder_id_ = root_folder_id;
66  }
67
68 private:
69  friend class DriveAPIParserTest;
70  FRIEND_TEST_ALL_PREFIXES(DriveAPIParserTest, AboutResourceParser);
71
72  // Parses and initializes data members from content of |value|.
73  // Return false if parsing fails.
74  bool Parse(const base::Value& value);
75
76  int64 largest_change_id_;
77  int64 quota_bytes_total_;
78  int64 quota_bytes_used_;
79  std::string root_folder_id_;
80
81  // This class is copyable on purpose.
82};
83
84// DriveAppIcon represents an icon for Drive Application.
85// https://developers.google.com/drive/v2/reference/apps
86class DriveAppIcon {
87 public:
88  enum IconCategory {
89    UNKNOWN,          // Uninitialized state.
90    DOCUMENT,         // Icon for a file associated with the app.
91    APPLICATION,      // Icon for the application.
92    SHARED_DOCUMENT,  // Icon for a shared file associated with the app.
93  };
94
95  DriveAppIcon();
96  ~DriveAppIcon();
97
98  // Registers the mapping between JSON field names and the members in this
99  // class.
100  static void RegisterJSONConverter(
101      base::JSONValueConverter<DriveAppIcon>* converter);
102
103  // Creates drive app icon instance from parsed JSON.
104  static scoped_ptr<DriveAppIcon> CreateFrom(const base::Value& value);
105
106  // Category of the icon.
107  IconCategory category() const { return category_; }
108
109  // Size in pixels of one side of the icon (icons are always square).
110  int icon_side_length() const { return icon_side_length_; }
111
112  // Returns URL for this icon.
113  const GURL& icon_url() const { return icon_url_; }
114
115  void set_category(IconCategory category) {
116    category_ = category;
117  }
118  void set_icon_side_length(int icon_side_length) {
119    icon_side_length_ = icon_side_length;
120  }
121  void set_icon_url(const GURL& icon_url) {
122    icon_url_ = icon_url;
123  }
124
125 private:
126  // Parses and initializes data members from content of |value|.
127  // Return false if parsing fails.
128  bool Parse(const base::Value& value);
129
130  // Extracts the icon category from the given string. Returns false and does
131  // not change |result| when |scheme| has an unrecognizable value.
132  static bool GetIconCategory(const base::StringPiece& category,
133                              IconCategory* result);
134
135  friend class base::internal::RepeatedMessageConverter<DriveAppIcon>;
136  friend class AppResource;
137
138  IconCategory category_;
139  int icon_side_length_;
140  GURL icon_url_;
141
142  DISALLOW_COPY_AND_ASSIGN(DriveAppIcon);
143};
144
145// AppResource represents a Drive Application.
146// https://developers.google.com/drive/v2/reference/apps
147class AppResource {
148 public:
149  ~AppResource();
150  AppResource();
151
152  // Registers the mapping between JSON field names and the members in this
153  // class.
154  static void RegisterJSONConverter(
155      base::JSONValueConverter<AppResource>* converter);
156
157  // Creates app resource from parsed JSON.
158  static scoped_ptr<AppResource> CreateFrom(const base::Value& value);
159
160  // Returns application ID, which is 12-digit decimals (e.g. "123456780123").
161  const std::string& application_id() const { return application_id_; }
162
163  // Returns application name.
164  const std::string& name() const { return name_; }
165
166  // Returns the name of the type of object this application creates.
167  // This is used for displaying in "Create" menu item for this app.
168  // If empty, application name is used instead.
169  const std::string& object_type() const { return object_type_; }
170
171  // Returns the product ID.
172  const std::string& product_id() const { return product_id_; }
173
174  // Returns whether this application supports creating new objects.
175  bool supports_create() const { return supports_create_; }
176
177  // Returns whether this application is removable by apps.delete API.
178  bool is_removable() const { return removable_; }
179
180  // Returns the create URL, i.e., the URL for opening a new file by the app.
181  const GURL& create_url() const { return create_url_; }
182
183  // List of primary mime types supported by this WebApp. Primary status should
184  // trigger this WebApp becoming the default handler of file instances that
185  // have these mime types.
186  const ScopedVector<std::string>& primary_mimetypes() const {
187    return primary_mimetypes_;
188  }
189
190  // List of secondary mime types supported by this WebApp. Secondary status
191  // should make this WebApp show up in "Open with..." pop-up menu of the
192  // default action menu for file with matching mime types.
193  const ScopedVector<std::string>& secondary_mimetypes() const {
194    return secondary_mimetypes_;
195  }
196
197  // List of primary file extensions supported by this WebApp. Primary status
198  // should trigger this WebApp becoming the default handler of file instances
199  // that match these extensions.
200  const ScopedVector<std::string>& primary_file_extensions() const {
201    return primary_file_extensions_;
202  }
203
204  // List of secondary file extensions supported by this WebApp. Secondary
205  // status should make this WebApp show up in "Open with..." pop-up menu of the
206  // default action menu for file with matching extensions.
207  const ScopedVector<std::string>& secondary_file_extensions() const {
208    return secondary_file_extensions_;
209  }
210
211  // Returns Icons for this application.  An application can have multiple
212  // icons for different purpose (application, document, shared document)
213  // in several sizes.
214  const ScopedVector<DriveAppIcon>& icons() const {
215    return icons_;
216  }
217
218  void set_application_id(const std::string& application_id) {
219    application_id_ = application_id;
220  }
221  void set_name(const std::string& name) { name_ = name; }
222  void set_object_type(const std::string& object_type) {
223    object_type_ = object_type;
224  }
225  void set_product_id(const std::string& id) { product_id_ = id; }
226  void set_supports_create(bool supports_create) {
227    supports_create_ = supports_create;
228  }
229  void set_removable(bool removable) { removable_ = removable; }
230  void set_primary_mimetypes(
231      ScopedVector<std::string> primary_mimetypes) {
232    primary_mimetypes_ = primary_mimetypes.Pass();
233  }
234  void set_secondary_mimetypes(
235      ScopedVector<std::string> secondary_mimetypes) {
236    secondary_mimetypes_ = secondary_mimetypes.Pass();
237  }
238  void set_primary_file_extensions(
239      ScopedVector<std::string> primary_file_extensions) {
240    primary_file_extensions_ = primary_file_extensions.Pass();
241  }
242  void set_secondary_file_extensions(
243      ScopedVector<std::string> secondary_file_extensions) {
244    secondary_file_extensions_ = secondary_file_extensions.Pass();
245  }
246  void set_icons(ScopedVector<DriveAppIcon> icons) {
247    icons_ = icons.Pass();
248  }
249  void set_create_url(const GURL& url) {
250    create_url_ = url;
251  }
252
253 private:
254  friend class base::internal::RepeatedMessageConverter<AppResource>;
255  friend class AppList;
256
257  // Parses and initializes data members from content of |value|.
258  // Return false if parsing fails.
259  bool Parse(const base::Value& value);
260
261  std::string application_id_;
262  std::string name_;
263  std::string object_type_;
264  std::string product_id_;
265  bool supports_create_;
266  bool removable_;
267  GURL create_url_;
268  ScopedVector<std::string> primary_mimetypes_;
269  ScopedVector<std::string> secondary_mimetypes_;
270  ScopedVector<std::string> primary_file_extensions_;
271  ScopedVector<std::string> secondary_file_extensions_;
272  ScopedVector<DriveAppIcon> icons_;
273
274  DISALLOW_COPY_AND_ASSIGN(AppResource);
275};
276
277// AppList represents a list of Drive Applications.
278// https://developers.google.com/drive/v2/reference/apps/list
279class AppList {
280 public:
281  AppList();
282  ~AppList();
283
284  // Registers the mapping between JSON field names and the members in this
285  // class.
286  static void RegisterJSONConverter(
287      base::JSONValueConverter<AppList>* converter);
288
289  // Creates app list from parsed JSON.
290  static scoped_ptr<AppList> CreateFrom(const base::Value& value);
291
292  // ETag for this resource.
293  const std::string& etag() const { return etag_; }
294
295  // Returns a vector of applications.
296  const ScopedVector<AppResource>& items() const { return items_; }
297
298  void set_etag(const std::string& etag) {
299    etag_ = etag;
300  }
301  void set_items(ScopedVector<AppResource> items) {
302    items_ = items.Pass();
303  }
304
305 private:
306  friend class DriveAPIParserTest;
307  FRIEND_TEST_ALL_PREFIXES(DriveAPIParserTest, AppListParser);
308
309  // Parses and initializes data members from content of |value|.
310  // Return false if parsing fails.
311  bool Parse(const base::Value& value);
312
313  std::string etag_;
314  ScopedVector<AppResource> items_;
315
316  DISALLOW_COPY_AND_ASSIGN(AppList);
317};
318
319// ParentReference represents a directory.
320// https://developers.google.com/drive/v2/reference/parents
321class ParentReference {
322 public:
323  ParentReference();
324  ~ParentReference();
325
326  // Registers the mapping between JSON field names and the members in this
327  // class.
328  static void RegisterJSONConverter(
329      base::JSONValueConverter<ParentReference>* converter);
330
331  // Creates parent reference from parsed JSON.
332  static scoped_ptr<ParentReference> CreateFrom(const base::Value& value);
333
334  // Returns the file id of the reference.
335  const std::string& file_id() const { return file_id_; }
336
337  // Returns the URL for the parent in Drive.
338  const GURL& parent_link() const { return parent_link_; }
339
340  void set_file_id(const std::string& file_id) { file_id_ = file_id; }
341  void set_parent_link(const GURL& parent_link) {
342    parent_link_ = parent_link;
343  }
344
345 private:
346  // Parses and initializes data members from content of |value|.
347  // Return false if parsing fails.
348  bool Parse(const base::Value& value);
349
350  std::string file_id_;
351  GURL parent_link_;
352};
353
354// FileLabels represents labels for file or folder.
355// https://developers.google.com/drive/v2/reference/files
356class FileLabels {
357 public:
358  FileLabels();
359  ~FileLabels();
360
361  // Registers the mapping between JSON field names and the members in this
362  // class.
363  static void RegisterJSONConverter(
364      base::JSONValueConverter<FileLabels>* converter);
365
366  // Creates about resource from parsed JSON.
367  static scoped_ptr<FileLabels> CreateFrom(const base::Value& value);
368
369  // Whether this file has been trashed.
370  bool is_trashed() const { return trashed_; }
371
372  void set_trashed(bool trashed) { trashed_ = trashed; }
373
374 private:
375  friend class FileResource;
376
377  // Parses and initializes data members from content of |value|.
378  // Return false if parsing fails.
379  bool Parse(const base::Value& value);
380
381  bool trashed_;
382};
383
384// ImageMediaMetadata represents image metadata for a file.
385// https://developers.google.com/drive/v2/reference/files
386class ImageMediaMetadata {
387 public:
388  ImageMediaMetadata();
389  ~ImageMediaMetadata();
390
391  // Registers the mapping between JSON field names and the members in this
392  // class.
393  static void RegisterJSONConverter(
394      base::JSONValueConverter<ImageMediaMetadata>* converter);
395
396  // Creates about resource from parsed JSON.
397  static scoped_ptr<ImageMediaMetadata> CreateFrom(const base::Value& value);
398
399  // Width of the image in pixels.
400  int width() const { return width_; }
401  // Height of the image in pixels.
402  int height() const { return height_; }
403  // Rotation of the image in clockwise degrees.
404  int rotation() const { return rotation_; }
405
406  void set_width(int width) { width_ = width; }
407  void set_height(int height) { height_ = height; }
408  void set_rotation(int rotation) { rotation_ = rotation; }
409
410 private:
411  friend class FileResource;
412
413  // Parses and initializes data members from content of |value|.
414  // Return false if parsing fails.
415  bool Parse(const base::Value& value);
416
417  int width_;
418  int height_;
419  int rotation_;
420};
421
422
423// FileResource represents a file or folder metadata in Drive.
424// https://developers.google.com/drive/v2/reference/files
425class FileResource {
426 public:
427  // Link to open a file resource on a web app with |app_id|.
428  struct OpenWithLink {
429    std::string app_id;
430    GURL open_url;
431  };
432
433  FileResource();
434  ~FileResource();
435
436  // Registers the mapping between JSON field names and the members in this
437  // class.
438  static void RegisterJSONConverter(
439      base::JSONValueConverter<FileResource>* converter);
440
441  // Creates file resource from parsed JSON.
442  static scoped_ptr<FileResource> CreateFrom(const base::Value& value);
443
444  // Returns true if this is a directory.
445  // Note: "folder" is used elsewhere in this file to match Drive API reference,
446  // but outside this file we use "directory" to match HTML5 filesystem API.
447  bool IsDirectory() const;
448
449  // Returns true if this is a hosted document.
450  // A hosted document is a document in one of Google Docs formats (Documents,
451  // Spreadsheets, Slides, ...) whose content is not exposed via the API. It is
452  // available only as |alternate_link()| to the document hosted on the server.
453  bool IsHostedDocument() const;
454
455  // Returns file ID.  This is unique in all files in Google Drive.
456  const std::string& file_id() const { return file_id_; }
457
458  // Returns ETag for this file.
459  const std::string& etag() const { return etag_; }
460
461  // Returns the title of this file.
462  const std::string& title() const { return title_; }
463
464  // Returns MIME type of this file.
465  const std::string& mime_type() const { return mime_type_; }
466
467  // Returns labels for this file.
468  const FileLabels& labels() const { return labels_; }
469
470  // Returns image media metadata for this file.
471  const ImageMediaMetadata& image_media_metadata() const {
472    return image_media_metadata_;
473  }
474
475  // Returns created time of this file.
476  const base::Time& created_date() const { return created_date_; }
477
478  // Returns modified time of this file.
479  const base::Time& modified_date() const { return modified_date_; }
480
481  // Returns last access time by the user.
482  const base::Time& last_viewed_by_me_date() const {
483    return last_viewed_by_me_date_;
484  }
485
486  // Returns time when the file was shared with the user.
487  const base::Time& shared_with_me_date() const {
488    return shared_with_me_date_;
489  }
490
491  // Returns the 'shared' attribute of the file.
492  bool shared() const { return shared_; }
493
494  // Returns MD5 checksum of this file.
495  const std::string& md5_checksum() const { return md5_checksum_; }
496
497  // Returns the size of this file in bytes.
498  int64 file_size() const { return file_size_; }
499
500  // Return the link to open the file in Google editor or viewer.
501  // E.g. Google Document, Google Spreadsheet.
502  const GURL& alternate_link() const { return alternate_link_; }
503
504  // Returns parent references (directories) of this file.
505  const std::vector<ParentReference>& parents() const { return parents_; }
506
507  // Returns the list of links to open the resource with a web app.
508  const std::vector<OpenWithLink>& open_with_links() const {
509    return open_with_links_;
510  }
511
512  void set_file_id(const std::string& file_id) {
513    file_id_ = file_id;
514  }
515  void set_etag(const std::string& etag) {
516    etag_ = etag;
517  }
518  void set_title(const std::string& title) {
519    title_ = title;
520  }
521  void set_mime_type(const std::string& mime_type) {
522    mime_type_ = mime_type;
523  }
524  FileLabels* mutable_labels() {
525    return &labels_;
526  }
527  ImageMediaMetadata* mutable_image_media_metadata() {
528    return &image_media_metadata_;
529  }
530  void set_created_date(const base::Time& created_date) {
531    created_date_ = created_date;
532  }
533  void set_modified_date(const base::Time& modified_date) {
534    modified_date_ = modified_date;
535  }
536  void set_last_viewed_by_me_date(const base::Time& last_viewed_by_me_date) {
537    last_viewed_by_me_date_ = last_viewed_by_me_date;
538  }
539  void set_shared_with_me_date(const base::Time& shared_with_me_date) {
540    shared_with_me_date_ = shared_with_me_date;
541  }
542  void set_shared(bool shared) {
543    shared_ = shared;
544  }
545  void set_md5_checksum(const std::string& md5_checksum) {
546    md5_checksum_ = md5_checksum;
547  }
548  void set_file_size(int64 file_size) {
549    file_size_ = file_size;
550  }
551  void set_alternate_link(const GURL& alternate_link) {
552    alternate_link_ = alternate_link;
553  }
554  std::vector<ParentReference>* mutable_parents() { return &parents_; }
555  std::vector<OpenWithLink>* mutable_open_with_links() {
556    return &open_with_links_;
557  }
558
559 private:
560  friend class base::internal::RepeatedMessageConverter<FileResource>;
561  friend class ChangeResource;
562  friend class FileList;
563
564  // Parses and initializes data members from content of |value|.
565  // Return false if parsing fails.
566  bool Parse(const base::Value& value);
567
568  std::string file_id_;
569  std::string etag_;
570  std::string title_;
571  std::string mime_type_;
572  FileLabels labels_;
573  ImageMediaMetadata image_media_metadata_;
574  base::Time created_date_;
575  base::Time modified_date_;
576  base::Time last_viewed_by_me_date_;
577  base::Time shared_with_me_date_;
578  bool shared_;
579  std::string md5_checksum_;
580  int64 file_size_;
581  GURL alternate_link_;
582  std::vector<ParentReference> parents_;
583  std::vector<OpenWithLink> open_with_links_;
584};
585
586// FileList represents a collection of files and folders.
587// https://developers.google.com/drive/v2/reference/files/list
588class FileList {
589 public:
590  FileList();
591  ~FileList();
592
593  // Registers the mapping between JSON field names and the members in this
594  // class.
595  static void RegisterJSONConverter(
596      base::JSONValueConverter<FileList>* converter);
597
598  // Returns true if the |value| has kind field for FileList.
599  static bool HasFileListKind(const base::Value& value);
600
601  // Creates file list from parsed JSON.
602  static scoped_ptr<FileList> CreateFrom(const base::Value& value);
603
604  // Returns a link to the next page of files.  The URL includes the next page
605  // token.
606  const GURL& next_link() const { return next_link_; }
607
608  // Returns a set of files in this list.
609  const ScopedVector<FileResource>& items() const { return items_; }
610  ScopedVector<FileResource>* mutable_items() { return &items_; }
611
612  void set_next_link(const GURL& next_link) {
613    next_link_ = next_link;
614  }
615
616 private:
617  friend class DriveAPIParserTest;
618  FRIEND_TEST_ALL_PREFIXES(DriveAPIParserTest, FileListParser);
619
620  // Parses and initializes data members from content of |value|.
621  // Return false if parsing fails.
622  bool Parse(const base::Value& value);
623
624  GURL next_link_;
625  ScopedVector<FileResource> items_;
626
627  DISALLOW_COPY_AND_ASSIGN(FileList);
628};
629
630// ChangeResource represents a change in a file.
631// https://developers.google.com/drive/v2/reference/changes
632class ChangeResource {
633 public:
634  ChangeResource();
635  ~ChangeResource();
636
637  // Registers the mapping between JSON field names and the members in this
638  // class.
639  static void RegisterJSONConverter(
640      base::JSONValueConverter<ChangeResource>* converter);
641
642  // Creates change resource from parsed JSON.
643  static scoped_ptr<ChangeResource> CreateFrom(const base::Value& value);
644
645  // Returns change ID for this change.  This is a monotonically increasing
646  // number.
647  int64 change_id() const { return change_id_; }
648
649  // Returns a string file ID for corresponding file of the change.
650  const std::string& file_id() const { return file_id_; }
651
652  // Returns true if this file is deleted in the change.
653  bool is_deleted() const { return deleted_; }
654
655  // Returns FileResource of the file which the change refers to.
656  const FileResource* file() const { return file_.get(); }
657  FileResource* mutable_file() { return file_.get(); }
658
659  // Returns the time of this modification.
660  const base::Time& modification_date() const { return modification_date_; }
661
662  void set_change_id(int64 change_id) {
663    change_id_ = change_id;
664  }
665  void set_file_id(const std::string& file_id) {
666    file_id_ = file_id;
667  }
668  void set_deleted(bool deleted) {
669    deleted_ = deleted;
670  }
671  void set_file(scoped_ptr<FileResource> file) {
672    file_ = file.Pass();
673  }
674  void set_modification_date(const base::Time& modification_date) {
675    modification_date_ = modification_date;
676  }
677
678 private:
679  friend class base::internal::RepeatedMessageConverter<ChangeResource>;
680  friend class ChangeList;
681
682  // Parses and initializes data members from content of |value|.
683  // Return false if parsing fails.
684  bool Parse(const base::Value& value);
685
686  int64 change_id_;
687  std::string file_id_;
688  bool deleted_;
689  scoped_ptr<FileResource> file_;
690  base::Time modification_date_;
691
692  DISALLOW_COPY_AND_ASSIGN(ChangeResource);
693};
694
695// ChangeList represents a set of changes in the drive.
696// https://developers.google.com/drive/v2/reference/changes/list
697class ChangeList {
698 public:
699  ChangeList();
700  ~ChangeList();
701
702  // Registers the mapping between JSON field names and the members in this
703  // class.
704  static void RegisterJSONConverter(
705      base::JSONValueConverter<ChangeList>* converter);
706
707  // Returns true if the |value| has kind field for ChangeList.
708  static bool HasChangeListKind(const base::Value& value);
709
710  // Creates change list from parsed JSON.
711  static scoped_ptr<ChangeList> CreateFrom(const base::Value& value);
712
713  // Returns a link to the next page of files.  The URL includes the next page
714  // token.
715  const GURL& next_link() const { return next_link_; }
716
717  // Returns the largest change ID number.
718  int64 largest_change_id() const { return largest_change_id_; }
719
720  // Returns a set of changes in this list.
721  const ScopedVector<ChangeResource>& items() const { return items_; }
722  ScopedVector<ChangeResource>* mutable_items() { return &items_; }
723
724  void set_next_link(const GURL& next_link) {
725    next_link_ = next_link;
726  }
727  void set_largest_change_id(int64 largest_change_id) {
728    largest_change_id_ = largest_change_id;
729  }
730
731 private:
732  friend class DriveAPIParserTest;
733  FRIEND_TEST_ALL_PREFIXES(DriveAPIParserTest, ChangeListParser);
734
735  // Parses and initializes data members from content of |value|.
736  // Return false if parsing fails.
737  bool Parse(const base::Value& value);
738
739  GURL next_link_;
740  int64 largest_change_id_;
741  ScopedVector<ChangeResource> items_;
742
743  DISALLOW_COPY_AND_ASSIGN(ChangeList);
744};
745
746}  // namespace google_apis
747
748#endif  // GOOGLE_APIS_DRIVE_DRIVE_API_PARSER_H_
749