Home | History | Annotate | Download | only in drive
      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_GDATA_WAPI_PARSER_H_
      6 #define GOOGLE_APIS_DRIVE_GDATA_WAPI_PARSER_H_
      7 
      8 #include <string>
      9 #include <utility>
     10 #include <vector>
     11 
     12 #include "base/compiler_specific.h"
     13 #include "base/memory/scoped_ptr.h"
     14 #include "base/memory/scoped_vector.h"
     15 #include "base/strings/string_piece.h"
     16 #include "base/time/time.h"
     17 #include "google_apis/drive/drive_entry_kinds.h"
     18 #include "url/gurl.h"
     19 
     20 namespace base {
     21 class FilePath;
     22 class DictionaryValue;
     23 class Value;
     24 
     25 template <class StructType>
     26 class JSONValueConverter;
     27 
     28 namespace internal {
     29 template <class NestedType>
     30 class RepeatedMessageConverter;
     31 }  // namespace internal
     32 
     33 }  // namespace base
     34 
     35 // Defines data elements of Google Documents API as described in
     36 // http://code.google.com/apis/documents/.
     37 namespace google_apis {
     38 
     39 // Defines link (URL) of an entity (document, file, feed...). Each entity could
     40 // have more than one link representing it.
     41 class Link {
     42  public:
     43   enum LinkType {
     44     LINK_UNKNOWN,
     45     LINK_SELF,
     46     LINK_NEXT,
     47     LINK_PARENT,
     48     LINK_ALTERNATE,
     49     LINK_EDIT,
     50     LINK_EDIT_MEDIA,
     51     LINK_ALT_EDIT_MEDIA,
     52     LINK_ALT_POST,
     53     LINK_FEED,
     54     LINK_POST,
     55     LINK_BATCH,
     56     LINK_RESUMABLE_EDIT_MEDIA,
     57     LINK_RESUMABLE_CREATE_MEDIA,
     58     LINK_TABLES_FEED,
     59     LINK_WORKSHEET_FEED,
     60     LINK_THUMBNAIL,
     61     LINK_EMBED,
     62     LINK_PRODUCT,
     63     LINK_ICON,
     64     LINK_OPEN_WITH,
     65     LINK_SHARE,
     66   };
     67   Link();
     68   ~Link();
     69 
     70   // Registers the mapping between JSON field names and the members in
     71   // this class.
     72   static void RegisterJSONConverter(base::JSONValueConverter<Link>* converter);
     73 
     74   // Type of the link.
     75   LinkType type() const { return type_; }
     76 
     77   // URL of the link.
     78   const GURL& href() const { return href_; }
     79 
     80   // Title of the link.
     81   const std::string& title() const { return title_; }
     82 
     83   // For OPEN_WITH links, this contains the application ID. For all other link
     84   // types, it is the empty string.
     85   const std::string& app_id() const { return app_id_; }
     86 
     87   // Link MIME type.
     88   const std::string& mime_type() const { return mime_type_; }
     89 
     90   void set_type(LinkType type) { type_ = type; }
     91   void set_href(const GURL& href) { href_ = href; }
     92   void set_title(const std::string& title) { title_ = title; }
     93   void set_app_id(const std::string& app_id) { app_id_ = app_id; }
     94   void set_mime_type(const std::string& mime_type) { mime_type_ = mime_type; }
     95 
     96  private:
     97   friend class ResourceEntry;
     98   // Converts value of link.rel into LinkType. Outputs to |type| and returns
     99   // true when |rel| has a valid value. Otherwise does nothing and returns
    100   // false.
    101   static bool GetLinkType(const base::StringPiece& rel, LinkType* type);
    102 
    103   // Converts value of link.rel to application ID, if there is one embedded in
    104   // the link.rel field. Outputs to |app_id| and returns true when |rel| has a
    105   // valid value. Otherwise does nothing and returns false.
    106   static bool GetAppID(const base::StringPiece& rel, std::string* app_id);
    107 
    108   LinkType type_;
    109   GURL href_;
    110   std::string title_;
    111   std::string app_id_;
    112   std::string mime_type_;
    113 
    114   DISALLOW_COPY_AND_ASSIGN(Link);
    115 };
    116 
    117 // Feed links define links (URLs) to special list of entries (i.e. list of
    118 // previous document revisions).
    119 class ResourceLink {
    120  public:
    121   enum ResourceLinkType {
    122     FEED_LINK_UNKNOWN,
    123     FEED_LINK_ACL,
    124     FEED_LINK_REVISIONS,
    125   };
    126   ResourceLink();
    127 
    128   // Registers the mapping between JSON field names and the members in
    129   // this class.
    130   static void RegisterJSONConverter(
    131       base::JSONValueConverter<ResourceLink>* converter);
    132 
    133   // MIME type of the feed.
    134   ResourceLinkType type() const { return type_; }
    135 
    136   // URL of the feed.
    137   const GURL& href() const { return href_; }
    138 
    139   void set_type(ResourceLinkType type) { type_ = type; }
    140   void set_href(const GURL& href) { href_ = href; }
    141 
    142  private:
    143   friend class ResourceEntry;
    144   // Converts value of gd$feedLink.rel into ResourceLinkType enum.
    145   // Outputs to |result| and returns true when |rel| has a valid
    146   // value.  Otherwise does nothing and returns false.
    147   static bool GetFeedLinkType(
    148       const base::StringPiece& rel, ResourceLinkType* result);
    149 
    150   ResourceLinkType type_;
    151   GURL href_;
    152 
    153   DISALLOW_COPY_AND_ASSIGN(ResourceLink);
    154 };
    155 
    156 // Author represents an author of an entity.
    157 class Author {
    158  public:
    159   Author();
    160 
    161   // Registers the mapping between JSON field names and the members in
    162   // this class.
    163   static void RegisterJSONConverter(
    164       base::JSONValueConverter<Author>* converter);
    165 
    166   // Getters.
    167   const std::string& name() const { return name_; }
    168   const std::string& email() const { return email_; }
    169 
    170   void set_name(const std::string& name) { name_ = name; }
    171   void set_email(const std::string& email) { email_ = email; }
    172 
    173  private:
    174   friend class ResourceEntry;
    175 
    176   std::string name_;
    177   std::string email_;
    178 
    179   DISALLOW_COPY_AND_ASSIGN(Author);
    180 };
    181 
    182 // Entry category.
    183 class Category {
    184  public:
    185   enum CategoryType {
    186     CATEGORY_UNKNOWN,
    187     CATEGORY_ITEM,
    188     CATEGORY_KIND,
    189     CATEGORY_LABEL,
    190   };
    191 
    192   Category();
    193 
    194   // Registers the mapping between JSON field names and the members in
    195   // this class.
    196   static void RegisterJSONConverter(
    197       base::JSONValueConverter<Category>* converter);
    198 
    199   // Category label.
    200   const std::string& label() const { return label_; }
    201 
    202   // Category type.
    203   CategoryType type() const { return type_; }
    204 
    205   // Category term.
    206   const std::string& term() const { return term_; }
    207 
    208   void set_label(const std::string& label) { label_ = label; }
    209   void set_type(CategoryType type) { type_ = type; }
    210   void set_term(const std::string& term) { term_ = term; }
    211 
    212  private:
    213   friend class ResourceEntry;
    214   // Converts category scheme into CategoryType enum. For example,
    215   // http://schemas.google.com/g/2005#kind => Category::CATEGORY_KIND
    216   // Returns false and does not change |result| when |scheme| has an
    217   // unrecognizable value.
    218   static bool GetCategoryTypeFromScheme(
    219       const base::StringPiece& scheme, CategoryType* result);
    220 
    221   std::string label_;
    222   CategoryType type_;
    223   std::string term_;
    224 
    225   DISALLOW_COPY_AND_ASSIGN(Category);
    226 };
    227 
    228 // Content details of a resource: mime-type, url, and so on.
    229 class Content {
    230  public:
    231   Content();
    232 
    233   // Registers the mapping between JSON field names and the members in
    234   // this class.
    235   static void RegisterJSONConverter(
    236       base::JSONValueConverter<Content>* converter);
    237 
    238   // The URL to download the file content.
    239   // Note that the url can expire, so we'll fetch the latest resource
    240   // entry before starting a download to get the download URL.
    241   const GURL& url() const { return url_; }
    242   const std::string& mime_type() const { return mime_type_; }
    243 
    244   void set_url(const GURL& url) { url_ = url; }
    245   void set_mime_type(const std::string& mime_type) { mime_type_ = mime_type; }
    246 
    247  private:
    248   friend class ResourceEntry;
    249 
    250   GURL url_;
    251   std::string mime_type_;
    252 };
    253 
    254 // This stores a representation of an application icon as registered with the
    255 // installed applications section of the account metadata feed. There can be
    256 // multiple icons registered for each application, differing in size, category
    257 // and MIME type.
    258 class AppIcon {
    259  public:
    260   enum IconCategory {
    261     ICON_UNKNOWN,          // Uninitialized state
    262     ICON_DOCUMENT,         // Document icon for various MIME types
    263     ICON_APPLICATION,      // Application icon for various MIME types
    264     ICON_SHARED_DOCUMENT,  // Icon for documents that are shared from other
    265                            // users.
    266   };
    267 
    268   AppIcon();
    269   ~AppIcon();
    270 
    271   // Registers the mapping between JSON field names and the members in
    272   // this class.
    273   static void RegisterJSONConverter(
    274       base::JSONValueConverter<AppIcon>* converter);
    275 
    276   // Category of the icon.
    277   IconCategory category() const { return category_; }
    278 
    279   // Size in pixels of one side of the icon (icons are always square).
    280   int icon_side_length() const { return icon_side_length_; }
    281 
    282   // Get a list of links available for this AppIcon.
    283   const ScopedVector<Link>& links() const { return links_; }
    284 
    285   // Get the icon URL from the internal list of links.  Returns the first
    286   // icon URL found in the list.
    287   GURL GetIconURL() const;
    288 
    289   void set_category(IconCategory category) { category_ = category; }
    290   void set_icon_side_length(int icon_side_length) {
    291     icon_side_length_ = icon_side_length;
    292   }
    293   void set_links(ScopedVector<Link> links) { links_ = links.Pass(); }
    294 
    295  private:
    296   // Extracts the icon category from the given string. Returns false and does
    297   // not change |result| when |scheme| has an unrecognizable value.
    298   static bool GetIconCategory(const base::StringPiece& category,
    299                               IconCategory* result);
    300 
    301   IconCategory category_;
    302   int icon_side_length_;
    303   ScopedVector<Link> links_;
    304 
    305   DISALLOW_COPY_AND_ASSIGN(AppIcon);
    306 };
    307 
    308 // Base class for feed entries. This class defines fields commonly used by
    309 // various feeds.
    310 class CommonMetadata {
    311  public:
    312   CommonMetadata();
    313   virtual ~CommonMetadata();
    314 
    315   // Returns a link of a given |type| for this entry. If not found, it returns
    316   // NULL.
    317   const Link* GetLinkByType(Link::LinkType type) const;
    318 
    319   // Entry update time.
    320   base::Time updated_time() const { return updated_time_; }
    321 
    322   // Entry ETag.
    323   const std::string& etag() const { return etag_; }
    324 
    325   // List of entry authors.
    326   const ScopedVector<Author>& authors() const { return authors_; }
    327 
    328   // List of entry links.
    329   const ScopedVector<Link>& links() const { return links_; }
    330   ScopedVector<Link>* mutable_links() { return &links_; }
    331 
    332   // List of entry categories.
    333   const ScopedVector<Category>& categories() const { return categories_; }
    334 
    335   void set_etag(const std::string& etag) { etag_ = etag; }
    336   void set_authors(ScopedVector<Author> authors) {
    337     authors_ = authors.Pass();
    338   }
    339   void set_links(ScopedVector<Link> links) {
    340     links_ = links.Pass();
    341   }
    342   void set_categories(ScopedVector<Category> categories) {
    343     categories_ = categories.Pass();
    344   }
    345   void set_updated_time(const base::Time& updated_time) {
    346     updated_time_ = updated_time;
    347   }
    348 
    349  protected:
    350   // Registers the mapping between JSON field names and the members in
    351   // this class.
    352   template<typename CommonMetadataDescendant>
    353   static void RegisterJSONConverter(
    354       base::JSONValueConverter<CommonMetadataDescendant>* converter);
    355 
    356   std::string etag_;
    357   ScopedVector<Author> authors_;
    358   ScopedVector<Link> links_;
    359   ScopedVector<Category> categories_;
    360   base::Time updated_time_;
    361 
    362   DISALLOW_COPY_AND_ASSIGN(CommonMetadata);
    363 };
    364 
    365 // This class represents a resource entry. A resource is a generic term which
    366 // refers to a file and a directory.
    367 class ResourceEntry : public CommonMetadata {
    368  public:
    369   ResourceEntry();
    370   virtual ~ResourceEntry();
    371 
    372   // Extracts "entry" dictionary from the JSON value, and parse the contents,
    373   // using CreateFrom(). Returns NULL on failure. The input JSON data, coming
    374   // from the gdata server, looks like:
    375   //
    376   // {
    377   //   "encoding": "UTF-8",
    378   //   "entry": { ... },   // This function will extract this and parse.
    379   //   "version": "1.0"
    380   // }
    381   //
    382   // The caller should delete the returned object.
    383   static scoped_ptr<ResourceEntry> ExtractAndParse(const base::Value& value);
    384 
    385   // Creates resource entry from parsed JSON Value.  You should call
    386   // this instead of instantiating JSONValueConverter by yourself
    387   // because this method does some post-process for some fields.  See
    388   // FillRemainingFields comment and implementation for the details.
    389   static scoped_ptr<ResourceEntry> CreateFrom(const base::Value& value);
    390 
    391   // Returns name of entry node.
    392   static std::string GetEntryNodeName();
    393 
    394   // Registers the mapping between JSON field names and the members in
    395   // this class.
    396   static void RegisterJSONConverter(
    397       base::JSONValueConverter<ResourceEntry>* converter);
    398 
    399   // Sets true to |result| if the field exists.
    400   // Always returns true even when the field does not exist.
    401   static bool HasFieldPresent(const base::Value* value, bool* result);
    402 
    403   // Parses |value| as int64 and sets it to |result|. If the field does not
    404   // exist, sets 0 to |result| as default value.
    405   // Returns true if |value| is NULL or it is parsed as int64 successfully.
    406   static bool ParseChangestamp(const base::Value* value, int64* result);
    407 
    408   // The resource ID is used to identify a resource, which looks like:
    409   // file:d41d8cd98f00b204e9800998ecf8
    410   const std::string& resource_id() const { return resource_id_; }
    411 
    412   // This is a URL looks like:
    413   // https://docs.google.com/feeds/id/file%3Ad41d8cd98f00b204e9800998ecf8.
    414   // The URL is currently not used.
    415   const std::string& id() const { return id_; }
    416 
    417   DriveEntryKind kind() const { return kind_; }
    418   const std::string& title() const { return title_; }
    419   base::Time published_time() const { return published_time_; }
    420   base::Time last_viewed_time() const { return last_viewed_time_; }
    421   const std::vector<std::string>& labels() const { return labels_; }
    422 
    423   // The URL to download a file content.
    424   // Search for 'download_url' in gdata_wapi_requests.h for details.
    425   const GURL& download_url() const { return content_.url(); }
    426 
    427   const std::string& content_mime_type() const { return content_.mime_type(); }
    428 
    429   // The resource links contain extra links for revisions and access control,
    430   // etc.  Note that links() contain more basic links like edit URL,
    431   // alternative URL, etc.
    432   const ScopedVector<ResourceLink>& resource_links() const {
    433     return resource_links_;
    434   }
    435 
    436   // File name (exists only for kinds FILE and PDF).
    437   const std::string& filename() const { return filename_; }
    438 
    439   // Suggested file name (exists only for kinds FILE and PDF).
    440   const std::string& suggested_filename() const { return suggested_filename_; }
    441 
    442   // File content MD5 (exists only for kinds FILE and PDF).
    443   const std::string& file_md5() const { return file_md5_; }
    444 
    445   // File size (exists only for kinds FILE and PDF).
    446   int64 file_size() const { return file_size_; }
    447 
    448   // True if the file or directory is deleted (applicable to change list only).
    449   bool deleted() const { return deleted_ || removed_; }
    450 
    451   // Changestamp (exists only for change query results).
    452   // If not exists, defaults to 0.
    453   int64 changestamp() const { return changestamp_; }
    454 
    455   // Image width (exists only for images).
    456   // If doesn't exist, then equals -1.
    457   int64 image_width() const { return image_width_; }
    458 
    459   // Image height (exists only for images).
    460   // If doesn't exist, then equals -1.
    461   int64 image_height() const { return image_height_; }
    462 
    463   // Image rotation in clockwise degrees (exists only for images).
    464   // If doesn't exist, then equals -1.
    465   int64 image_rotation() const { return image_rotation_; }
    466 
    467   // Text version of resource entry kind. Returns an empty string for
    468   // unknown entry kind.
    469   std::string GetEntryKindText() const;
    470 
    471   // Returns preferred file extension for hosted documents. If entry is not
    472   // a hosted document, this call returns an empty string.
    473   std::string GetHostedDocumentExtension() const;
    474 
    475   // True if resource entry is remotely hosted.
    476   bool is_hosted_document() const {
    477     return (ClassifyEntryKind(kind_) & KIND_OF_HOSTED_DOCUMENT) > 0;
    478   }
    479   // True if resource entry hosted by Google Documents.
    480   bool is_google_document() const {
    481     return (ClassifyEntryKind(kind_) & KIND_OF_GOOGLE_DOCUMENT) > 0;
    482   }
    483   // True if resource entry is hosted by an external application.
    484   bool is_external_document() const {
    485     return (ClassifyEntryKind(kind_) & KIND_OF_EXTERNAL_DOCUMENT) > 0;
    486   }
    487   // True if resource entry is a folder (collection).
    488   bool is_folder() const {
    489     return (ClassifyEntryKind(kind_) & KIND_OF_FOLDER) > 0;
    490   }
    491   // True if resource entry is regular file.
    492   bool is_file() const {
    493     return (ClassifyEntryKind(kind_) & KIND_OF_FILE) > 0;
    494   }
    495   // True if resource entry can't be mapped to the file system.
    496   bool is_special() const {
    497     return !is_file() && !is_folder() && !is_hosted_document();
    498   }
    499 
    500   // The following constructs are exposed for unit tests.
    501 
    502   // Classes of EntryKind. Used for ClassifyEntryKind().
    503   enum EntryKindClass {
    504     KIND_OF_NONE = 0,
    505     KIND_OF_HOSTED_DOCUMENT = 1,
    506     KIND_OF_GOOGLE_DOCUMENT = 1 << 1,
    507     KIND_OF_EXTERNAL_DOCUMENT = 1 << 2,
    508     KIND_OF_FOLDER = 1 << 3,
    509     KIND_OF_FILE = 1 << 4,
    510   };
    511 
    512   // Classifies the EntryKind. The returned value is a bitmask of
    513   // EntryKindClass. For example, DOCUMENT is classified as
    514   // KIND_OF_HOSTED_DOCUMENT and KIND_OF_GOOGLE_DOCUMENT, hence the returned
    515   // value is KIND_OF_HOSTED_DOCUMENT | KIND_OF_GOOGLE_DOCUMENT.
    516   static int ClassifyEntryKind(DriveEntryKind kind);
    517 
    518   // Classifies the EntryKind by the file extension of specific path. The
    519   // returned value is a bitmask of EntryKindClass. See also ClassifyEntryKind.
    520   static int ClassifyEntryKindByFileExtension(const base::FilePath& file);
    521 
    522   void set_resource_id(const std::string& resource_id) {
    523     resource_id_ = resource_id;
    524   }
    525   void set_id(const std::string& id) { id_ = id; }
    526   void set_kind(DriveEntryKind kind) { kind_ = kind; }
    527   void set_title(const std::string& title) { title_ = title; }
    528   void set_published_time(const base::Time& published_time) {
    529     published_time_ = published_time;
    530   }
    531   void set_last_viewed_time(const base::Time& last_viewed_time) {
    532     last_viewed_time_ = last_viewed_time;
    533   }
    534   void set_labels(const std::vector<std::string>& labels) {
    535     labels_ = labels;
    536   }
    537   void set_content(const Content& content) {
    538     content_ = content;
    539   }
    540   void set_resource_links(ScopedVector<ResourceLink> resource_links) {
    541     resource_links_ = resource_links.Pass();
    542   }
    543   void set_filename(const std::string& filename) { filename_ = filename; }
    544   void set_suggested_filename(const std::string& suggested_filename) {
    545     suggested_filename_ = suggested_filename;
    546   }
    547   void set_file_md5(const std::string& file_md5) { file_md5_ = file_md5; }
    548   void set_file_size(int64 file_size) { file_size_ = file_size; }
    549   void set_deleted(bool deleted) { deleted_ = deleted; }
    550   void set_removed(bool removed) { removed_ = removed; }
    551   void set_changestamp(int64 changestamp) { changestamp_ = changestamp; }
    552   void set_image_width(int64 image_width) { image_width_ = image_width; }
    553   void set_image_height(int64 image_height) { image_height_ = image_height; }
    554   void set_image_rotation(int64 image_rotation) {
    555     image_rotation_ = image_rotation;
    556   }
    557 
    558   // Fills the remaining fields where JSONValueConverter cannot catch.
    559   // Currently, sets |kind_| and |labels_| based on the |categories_| in the
    560   // class.
    561   void FillRemainingFields();
    562 
    563  private:
    564   friend class base::internal::RepeatedMessageConverter<ResourceEntry>;
    565   friend class ResourceList;
    566   friend class ResumeUploadRequest;
    567 
    568   // Converts categories.term into DriveEntryKind enum.
    569   static DriveEntryKind GetEntryKindFromTerm(const std::string& term);
    570   // Converts |kind| into its text identifier equivalent.
    571   static const char* GetEntryKindDescription(DriveEntryKind kind);
    572 
    573   std::string resource_id_;
    574   std::string id_;
    575   DriveEntryKind kind_;
    576   std::string title_;
    577   base::Time published_time_;
    578   // Last viewed value may be unreliable. See: crbug.com/152628.
    579   base::Time last_viewed_time_;
    580   std::vector<std::string> labels_;
    581   Content content_;
    582   ScopedVector<ResourceLink> resource_links_;
    583   // Optional fields for files only.
    584   std::string filename_;
    585   std::string suggested_filename_;
    586   std::string file_md5_;
    587   int64 file_size_;
    588   bool deleted_;
    589   bool removed_;
    590   int64 changestamp_;
    591   int64 image_width_;
    592   int64 image_height_;
    593   int64 image_rotation_;
    594 
    595   DISALLOW_COPY_AND_ASSIGN(ResourceEntry);
    596 };
    597 
    598 // This class represents a list of resource entries with some extra metadata
    599 // such as the root upload URL. The feed is paginated and the rest of the
    600 // feed can be fetched by retrieving the remaining parts of the feed from
    601 // URLs provided by GetNextFeedURL() method.
    602 class ResourceList : public CommonMetadata {
    603  public:
    604   ResourceList();
    605   virtual ~ResourceList();
    606 
    607   // Extracts "feed" dictionary from the JSON value, and parse the contents,
    608   // using CreateFrom(). Returns NULL on failure. The input JSON data, coming
    609   // from the gdata server, looks like:
    610   //
    611   // {
    612   //   "encoding": "UTF-8",
    613   //   "feed": { ... },   // This function will extract this and parse.
    614   //   "version": "1.0"
    615   // }
    616   static scoped_ptr<ResourceList> ExtractAndParse(const base::Value& value);
    617 
    618   // Creates feed from parsed JSON Value.  You should call this
    619   // instead of instantiating JSONValueConverter by yourself because
    620   // this method does some post-process for some fields.  See
    621   // FillRemainingFields comment and implementation in ResourceEntry
    622   // class for the details.
    623   static scoped_ptr<ResourceList> CreateFrom(const base::Value& value);
    624 
    625   // Registers the mapping between JSON field names and the members in
    626   // this class.
    627   static void RegisterJSONConverter(
    628       base::JSONValueConverter<ResourceList>* converter);
    629 
    630   // Returns true and passes|url| of the next feed if the current entry list
    631   // does not completed this feed.
    632   bool GetNextFeedURL(GURL* url) const;
    633 
    634   // List of resource entries.
    635   const ScopedVector<ResourceEntry>& entries() const { return entries_; }
    636   ScopedVector<ResourceEntry>* mutable_entries() { return &entries_; }
    637 
    638   // Releases entries_ into |entries|. This is a transfer of ownership, so the
    639   // caller is responsible for deleting the elements of |entries|.
    640   void ReleaseEntries(std::vector<ResourceEntry*>* entries);
    641 
    642   // Start index of the resource entry list.
    643   int start_index() const { return start_index_; }
    644 
    645   // Number of items per feed of the resource entry list.
    646   int items_per_page() const { return items_per_page_; }
    647 
    648   // The largest changestamp. Next time the resource list should be fetched
    649   // from this changestamp.
    650   int64 largest_changestamp() const { return largest_changestamp_; }
    651 
    652   // Resource entry list title.
    653   const std::string& title() { return title_; }
    654 
    655   void set_entries(ScopedVector<ResourceEntry> entries) {
    656     entries_ = entries.Pass();
    657   }
    658   void set_start_index(int start_index) {
    659     start_index_ = start_index;
    660   }
    661   void set_items_per_page(int items_per_page) {
    662     items_per_page_ = items_per_page;
    663   }
    664   void set_title(const std::string& title) {
    665     title_ = title;
    666   }
    667   void set_largest_changestamp(int64 largest_changestamp) {
    668     largest_changestamp_ = largest_changestamp;
    669   }
    670 
    671  private:
    672   // Parses and initializes data members from content of |value|.
    673   // Return false if parsing fails.
    674   bool Parse(const base::Value& value);
    675 
    676   ScopedVector<ResourceEntry> entries_;
    677   int start_index_;
    678   int items_per_page_;
    679   std::string title_;
    680   int64 largest_changestamp_;
    681 
    682   DISALLOW_COPY_AND_ASSIGN(ResourceList);
    683 };
    684 
    685 // Metadata representing installed Google Drive application.
    686 class InstalledApp {
    687  public:
    688   typedef std::vector<std::pair<int, GURL> > IconList;
    689 
    690   InstalledApp();
    691   virtual ~InstalledApp();
    692 
    693   // WebApp name.
    694   const std::string& app_name() const { return app_name_; }
    695 
    696   // Drive app id
    697   const std::string& app_id() const { return app_id_; }
    698 
    699   // Object (file) type name that is generated by this WebApp.
    700   const std::string& object_type() const { return object_type_; }
    701 
    702   // True if WebApp supports creation of new file instances.
    703   bool supports_create() const { return supports_create_; }
    704 
    705   // List of primary mime types supported by this WebApp. Primary status should
    706   // trigger this WebApp becoming the default handler of file instances that
    707   // have these mime types.
    708   const ScopedVector<std::string>& primary_mimetypes() const {
    709     return primary_mimetypes_;
    710   }
    711 
    712   // List of secondary mime types supported by this WebApp. Secondary status
    713   // should make this WebApp show up in "Open with..." pop-up menu of the
    714   // default action menu for file with matching mime types.
    715   const ScopedVector<std::string>& secondary_mimetypes() const {
    716     return secondary_mimetypes_;
    717   }
    718 
    719   // List of primary file extensions supported by this WebApp. Primary status
    720   // should trigger this WebApp becoming the default handler of file instances
    721   // that match these extensions.
    722   const ScopedVector<std::string>& primary_extensions() const {
    723     return primary_extensions_;
    724   }
    725 
    726   // List of secondary file extensions supported by this WebApp. Secondary
    727   // status should make this WebApp show up in "Open with..." pop-up menu of the
    728   // default action menu for file with matching extensions.
    729   const ScopedVector<std::string>& secondary_extensions() const {
    730     return secondary_extensions_;
    731   }
    732 
    733   // List of entry links.
    734   const ScopedVector<Link>& links() const { return links_; }
    735 
    736   // Returns a list of icons associated with this installed application.
    737   const ScopedVector<AppIcon>& app_icons() const {
    738     return app_icons_;
    739   }
    740 
    741   // Convenience function for getting the icon URLs for a particular |category|
    742   // of icon. Icons are returned in a sorted list, from smallest to largest.
    743   IconList GetIconsForCategory(AppIcon::IconCategory category) const;
    744 
    745   // Retrieves product URL from the link collection.
    746   GURL GetProductUrl() const;
    747 
    748   // Registers the mapping between JSON field names and the members in
    749   // this class.
    750   static void RegisterJSONConverter(
    751       base::JSONValueConverter<InstalledApp>* converter);
    752 
    753   void set_app_id(const std::string& app_id) { app_id_ = app_id; }
    754   void set_app_name(const std::string& app_name) { app_name_ = app_name; }
    755   void set_object_type(const std::string& object_type) {
    756     object_type_ = object_type;
    757   }
    758   void set_supports_create(bool supports_create) {
    759     supports_create_ = supports_create;
    760   }
    761   void set_primary_mimetypes(
    762       ScopedVector<std::string> primary_mimetypes) {
    763     primary_mimetypes_ = primary_mimetypes.Pass();
    764   }
    765   void set_secondary_mimetypes(
    766       ScopedVector<std::string> secondary_mimetypes) {
    767     secondary_mimetypes_ = secondary_mimetypes.Pass();
    768   }
    769   void set_primary_extensions(
    770       ScopedVector<std::string> primary_extensions) {
    771     primary_extensions_ = primary_extensions.Pass();
    772   }
    773   void set_secondary_extensions(
    774       ScopedVector<std::string> secondary_extensions) {
    775     secondary_extensions_ = secondary_extensions.Pass();
    776   }
    777   void set_links(ScopedVector<Link> links) {
    778     links_ = links.Pass();
    779   }
    780   void set_app_icons(ScopedVector<AppIcon> app_icons) {
    781     app_icons_ = app_icons.Pass();
    782   }
    783 
    784  private:
    785   // Extracts "$t" value from the dictionary |value| and returns it in |result|.
    786   // If the string value can't be found, it returns false.
    787   static bool GetValueString(const base::Value* value,
    788                              std::string* result);
    789 
    790   std::string app_id_;
    791   std::string app_name_;
    792   std::string object_type_;
    793   bool supports_create_;
    794   ScopedVector<std::string> primary_mimetypes_;
    795   ScopedVector<std::string> secondary_mimetypes_;
    796   ScopedVector<std::string> primary_extensions_;
    797   ScopedVector<std::string> secondary_extensions_;
    798   ScopedVector<Link> links_;
    799   ScopedVector<AppIcon> app_icons_;
    800 };
    801 
    802 // Account metadata feed represents the metadata object attached to the user's
    803 // account.
    804 class AccountMetadata {
    805  public:
    806   AccountMetadata();
    807   virtual ~AccountMetadata();
    808 
    809   // Creates feed from parsed JSON Value.  You should call this
    810   // instead of instantiating JSONValueConverter by yourself because
    811   // this method does some post-process for some fields.  See
    812   // FillRemainingFields comment and implementation in ResourceEntry
    813   // class for the details.
    814   static scoped_ptr<AccountMetadata> CreateFrom(const base::Value& value);
    815 
    816   int64 quota_bytes_total() const {
    817     return quota_bytes_total_;
    818   }
    819 
    820   int64 quota_bytes_used() const {
    821     return quota_bytes_used_;
    822   }
    823 
    824   int64 largest_changestamp() const {
    825     return largest_changestamp_;
    826   }
    827 
    828   const ScopedVector<InstalledApp>& installed_apps() const {
    829     return installed_apps_;
    830   }
    831 
    832   void set_quota_bytes_total(int64 quota_bytes_total) {
    833     quota_bytes_total_ = quota_bytes_total;
    834   }
    835   void set_quota_bytes_used(int64 quota_bytes_used) {
    836     quota_bytes_used_ = quota_bytes_used;
    837   }
    838   void set_largest_changestamp(int64 largest_changestamp) {
    839     largest_changestamp_ = largest_changestamp;
    840   }
    841   void set_installed_apps(ScopedVector<InstalledApp> installed_apps) {
    842     installed_apps_ = installed_apps.Pass();
    843   }
    844 
    845   // Registers the mapping between JSON field names and the members in
    846   // this class.
    847   static void RegisterJSONConverter(
    848       base::JSONValueConverter<AccountMetadata>* converter);
    849 
    850  private:
    851   // Parses and initializes data members from content of |value|.
    852   // Return false if parsing fails.
    853   bool Parse(const base::Value& value);
    854 
    855   int64 quota_bytes_total_;
    856   int64 quota_bytes_used_;
    857   int64 largest_changestamp_;
    858   ScopedVector<InstalledApp> installed_apps_;
    859 
    860   DISALLOW_COPY_AND_ASSIGN(AccountMetadata);
    861 };
    862 
    863 
    864 }  // namespace google_apis
    865 
    866 #endif  // GOOGLE_APIS_DRIVE_GDATA_WAPI_PARSER_H_
    867