15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/google_apis/gdata_wapi_parser.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm>
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h"
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/json/json_value_converter.h"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h"
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/strings/string_piece.h"
16868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h"
17868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/google_apis/drive_api_parser.h"
202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/google_apis/time_util.h"
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Value;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::DictionaryValue;
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::ListValue;
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace google_apis {
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace {
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Term values for kSchemeKind category:
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSchemeKind[] = "http://schemas.google.com/g/2005#kind";
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTermPrefix[] = "http://schemas.google.com/docs/2007#";
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFileTerm[] = "file";
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFolderTerm[] = "folder";
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kItemTerm[] = "item";
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPdfTerm[] = "pdf";
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kDocumentTerm[] = "document";
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSpreadSheetTerm[] = "spreadsheet";
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPresentationTerm[] = "presentation";
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSchemeLabels[] = "http://schemas.google.com/g/2005/labels";
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Node names.
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kAuthorNode[] = "author";
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kCategoryNode[] = "category";
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kContentNode[] = "content";
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kEditedNode[] = "edited";
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kEmailNode[] = "email";
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kEntryNode[] = "entry";
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFeedLinkNode[] = "feedLink";
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFilenameNode[] = "filename";
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kIDNode[] = "id";
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kLastModifiedByNode[] = "lastModifiedBy";
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kLastViewedNode[] = "lastViewed";
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kLinkNode[] = "link";
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kMd5ChecksumNode[] = "md5Checksum";
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kModifiedByMeDateNode[] = "modifiedByMeDate";
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kNameNode[] = "name";
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPublishedNode[] = "published";
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kQuotaBytesUsedNode[] = "quotaBytesUsed";
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kResourceIdNode[] = "resourceId";
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSizeNode[] = "size";
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSuggestedFilenameNode[] = "suggestedFilename";
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTitleNode[] = "title";
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUpdatedNode[] = "updated";
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kWritersCanInviteNode[] = "writersCanInvite";
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Field names.
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kAuthorField[] = "author";
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kCategoryField[] = "category";
712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const char kChangestampField[] = "docs$changestamp.value";
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kContentField[] = "content";
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kDeletedField[] = "gd$deleted";
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kETagField[] = "gd$etag";
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kEmailField[] = "email.$t";
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kEntryField[] = "entry";
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFeedField[] = "feed";
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFeedLinkField[] = "gd$feedLink";
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kFileNameField[] = "docs$filename.$t";
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kHrefField[] = "href";
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kIDField[] = "id.$t";
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInstalledAppField[] = "docs$installedApp";
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInstalledAppNameField[] = "docs$installedAppName";
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInstalledAppIdField[] = "docs$installedAppId";
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInstalledAppIconField[] = "docs$installedAppIcon";
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInstalledAppIconCategoryField[] = "docs$installedAppIconCategory";
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInstalledAppIconSizeField[] = "docs$installedAppIconSize";
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInstalledAppObjectTypeField[] = "docs$installedAppObjectType";
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInstalledAppPrimaryFileExtensionField[] =
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "docs$installedAppPrimaryFileExtension";
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInstalledAppPrimaryMimeTypeField[] =
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "docs$installedAppPrimaryMimeType";
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInstalledAppSecondaryFileExtensionField[] =
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "docs$installedAppSecondaryFileExtension";
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInstalledAppSecondaryMimeTypeField[] =
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "docs$installedAppSecondaryMimeType";
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kInstalledAppSupportsCreateField[] =
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    "docs$installedAppSupportsCreate";
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kItemsPerPageField[] = "openSearch$itemsPerPage.$t";
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kLabelField[] = "label";
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kLargestChangestampField[] = "docs$largestChangestamp.value";
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kLastViewedField[] = "gd$lastViewed.$t";
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kLinkField[] = "link";
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kMD5Field[] = "docs$md5Checksum.$t";
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kNameField[] = "name.$t";
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kPublishedField[] = "published.$t";
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kQuotaBytesTotalField[] = "gd$quotaBytesTotal.$t";
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kQuotaBytesUsedField[] = "gd$quotaBytesUsed.$t";
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kRelField[] = "rel";
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kRemovedField[] = "docs$removed";
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kResourceIdField[] = "gd$resourceId.$t";
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSchemeField[] = "scheme";
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSizeField[] = "docs$size.$t";
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSrcField[] = "src";
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kStartIndexField[] = "openSearch$startIndex.$t";
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSuggestedFileNameField[] = "docs$suggestedFilename.$t";
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTField[] = "$t";
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTermField[] = "term";
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTitleField[] = "title";
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTitleTField[] = "title.$t";
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTypeField[] = "type";
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kUpdatedField[] = "updated.$t";
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Attribute names.
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Attributes are not namespace-blind as node names in XmlReader.
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kETagAttr[] = "gd:etag";
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kEmailAttr[] = "email";
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kHrefAttr[] = "href";
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kLabelAttr[] = "label";
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kNameAttr[] = "name";
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kRelAttr[] = "rel";
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSchemeAttr[] = "scheme";
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kSrcAttr[] = "src";
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTermAttr[] = "term";
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTypeAttr[] = "type";
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kValueAttr[] = "value";
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Link Prefixes
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kOpenWithPrefix[] = "http://schemas.google.com/docs/2007#open-with-";
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const size_t kOpenWithPrefixSize = arraysize(kOpenWithPrefix) - 1;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct EntryKindMap {
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DriveEntryKind kind;
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* entry;
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* extension;
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const EntryKindMap kEntryKindMap[] = {
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ENTRY_KIND_UNKNOWN,      "unknown",      NULL},
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ENTRY_KIND_ITEM,         "item",         NULL},
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ENTRY_KIND_DOCUMENT,     "document",     ".gdoc"},
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ENTRY_KIND_SPREADSHEET,  "spreadsheet",  ".gsheet"},
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ENTRY_KIND_PRESENTATION, "presentation", ".gslides" },
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ENTRY_KIND_DRAWING,      "drawing",      ".gdraw"},
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ENTRY_KIND_TABLE,        "table",        ".gtable"},
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ENTRY_KIND_EXTERNAL_APP, "externalapp",  ".glink"},
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ENTRY_KIND_SITE,         "site",         NULL},
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ENTRY_KIND_FOLDER,       "folder",       NULL},
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ENTRY_KIND_FILE,         "file",         NULL},
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { ENTRY_KIND_PDF,          "pdf",          NULL},
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)COMPILE_ASSERT(arraysize(kEntryKindMap) == ENTRY_KIND_MAX_VALUE,
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)               EntryKindMap_and_DriveEntryKind_are_not_in_sync);
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct LinkTypeMap {
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Link::LinkType type;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* rel;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const LinkTypeMap kLinkTypeMap[] = {
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_SELF,
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "self" },
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_NEXT,
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "next" },
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_PARENT,
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://schemas.google.com/docs/2007#parent" },
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_ALTERNATE,
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "alternate"},
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_EDIT,
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "edit" },
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_EDIT_MEDIA,
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "edit-media" },
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_ALT_EDIT_MEDIA,
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://schemas.google.com/docs/2007#alt-edit-media" },
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_ALT_POST,
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://schemas.google.com/docs/2007#alt-post" },
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_FEED,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://schemas.google.com/g/2005#feed"},
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_POST,
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://schemas.google.com/g/2005#post"},
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_BATCH,
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://schemas.google.com/g/2005#batch"},
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_THUMBNAIL,
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://schemas.google.com/docs/2007/thumbnail"},
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_RESUMABLE_EDIT_MEDIA,
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://schemas.google.com/g/2005#resumable-edit-media"},
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_RESUMABLE_CREATE_MEDIA,
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://schemas.google.com/g/2005#resumable-create-media"},
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_TABLES_FEED,
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://schemas.google.com/spreadsheets/2006#tablesfeed"},
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_WORKSHEET_FEED,
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://schemas.google.com/spreadsheets/2006#worksheetsfeed"},
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_EMBED,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://schemas.google.com/docs/2007#embed"},
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_PRODUCT,
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://schemas.google.com/docs/2007#product"},
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_ICON,
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://schemas.google.com/docs/2007#icon"},
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Link::LINK_SHARE,
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://schemas.google.com/docs/2007#share"},
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)struct ResourceLinkTypeMap {
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ResourceLink::ResourceLinkType type;
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* rel;
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const ResourceLinkTypeMap kFeedLinkTypeMap[] = {
2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { ResourceLink::FEED_LINK_ACL,
2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://schemas.google.com/acl/2007#accessControlList" },
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    { ResourceLink::FEED_LINK_REVISIONS,
2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      "http://schemas.google.com/docs/2007/revisions" },
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct CategoryTypeMap {
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Category::CategoryType type;
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* scheme;
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const CategoryTypeMap kCategoryTypeMap[] = {
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Category::CATEGORY_KIND, "http://schemas.google.com/g/2005#kind" },
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { Category::CATEGORY_LABEL, "http://schemas.google.com/g/2005/labels" },
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct AppIconCategoryMap {
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppIcon::IconCategory category;
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const char* category_name;
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const AppIconCategoryMap kAppIconCategoryMap[] = {
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { AppIcon::ICON_DOCUMENT, "document" },
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { AppIcon::ICON_APPLICATION, "application" },
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    { AppIcon::ICON_SHARED_DOCUMENT, "documentShared" },
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converts |url_string| to |result|.  Always returns true to be used
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for JSONValueConverter::RegisterCustomField method.
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(mukai): make it return false in case of invalid |url_string|.
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetGURLFromString(const base::StringPiece& url_string, GURL* result) {
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *result = GURL(url_string.as_string());
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converts boolean string values like "true" into bool.
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool GetBoolFromString(const base::StringPiece& value, bool* result) {
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *result = (value == "true");
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SortBySize(const InstalledApp::IconList::value_type& a,
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                const InstalledApp::IconList::value_type& b) {
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return a.first < b.first;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Author implementation
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Author::Author() {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Author::RegisterJSONConverter(
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::JSONValueConverter<Author>* converter) {
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterStringField(kNameField, &Author::name_);
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterStringField(kEmailField, &Author::email_);
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Link implementation
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Link::Link() : type_(Link::LINK_UNKNOWN) {
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Link::~Link() {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Link::GetAppID(const base::StringPiece& rel, std::string* app_id) {
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(app_id);
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Fast return path if the link clearly isn't an OPEN_WITH link.
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rel.size() < kOpenWithPrefixSize) {
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    app_id->clear();
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const std::string kOpenWithPrefixStr(kOpenWithPrefix);
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (StartsWithASCII(rel.as_string(), kOpenWithPrefixStr, false)) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *app_id = rel.as_string().substr(kOpenWithPrefixStr.size());
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  app_id->clear();
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static.
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Link::GetLinkType(const base::StringPiece& rel, Link::LinkType* type) {
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(type);
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kLinkTypeMap); i++) {
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rel == kLinkTypeMap[i].rel) {
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *type = kLinkTypeMap[i].type;
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // OPEN_WITH links have extra information at the end of the rel that is unique
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // for each one, so we can't just check the usual map. This check is slightly
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // redundant to provide a quick skip if it's obviously not an OPEN_WITH url.
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (rel.size() >= kOpenWithPrefixSize &&
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      StartsWithASCII(rel.as_string(), kOpenWithPrefix, false)) {
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    *type = LINK_OPEN_WITH;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return true;
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Let unknown link types through, just report it; if the link type is needed
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in the future, add it into LinkType and kLinkTypeMap.
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Ignoring unknown link type for rel " << rel;
3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *type = LINK_UNKNOWN;
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Link::RegisterJSONConverter(base::JSONValueConverter<Link>* converter) {
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomField<Link::LinkType>(kRelField,
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 &Link::type_,
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                                 &Link::GetLinkType);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We have to register kRelField twice because we extract two different pieces
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // of data from the same rel field.
3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomField<std::string>(kRelField,
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              &Link::app_id_,
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                              &Link::GetAppID);
3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomField(kHrefField, &Link::href_, &GetGURLFromString);
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterStringField(kTitleField, &Link::title_);
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterStringField(kTypeField, &Link::mime_type_);
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
3502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ResourceLink implementation
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceLink::ResourceLink() : type_(ResourceLink::FEED_LINK_UNKNOWN) {
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static.
3562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ResourceLink::GetFeedLinkType(
3572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    const base::StringPiece& rel, ResourceLink::ResourceLinkType* result) {
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kFeedLinkTypeMap); i++) {
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (rel == kFeedLinkTypeMap[i].rel) {
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *result = kFeedLinkTypeMap[i].type;
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Unknown feed link type for rel " << rel;
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceLink::RegisterJSONConverter(
3702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::JSONValueConverter<ResourceLink>* converter) {
3712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  converter->RegisterCustomField<ResourceLink::ResourceLinkType>(
3722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kRelField, &ResourceLink::type_, &ResourceLink::GetFeedLinkType);
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomField(
3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kHrefField, &ResourceLink::href_, &GetGURLFromString);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Category implementation
3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Category::Category() : type_(CATEGORY_UNKNOWN) {
3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Converts category.scheme into CategoryType enum.
3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool Category::GetCategoryTypeFromScheme(
3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::StringPiece& scheme, Category::CategoryType* result) {
3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kCategoryTypeMap); i++) {
3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (scheme == kCategoryTypeMap[i].scheme) {
3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *result = kCategoryTypeMap[i].type;
3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Unknown feed link type for scheme " << scheme;
3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Category::RegisterJSONConverter(
3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::JSONValueConverter<Category>* converter) {
3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterStringField(kLabelField, &Category::label_);
4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomField<Category::CategoryType>(
4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kSchemeField, &Category::type_, &Category::GetCategoryTypeFromScheme);
4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterStringField(kTermField, &Category::term_);
4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const Link* CommonMetadata::GetLinkByType(Link::LinkType type) const {
4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < links_.size(); ++i) {
4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (links_[i]->type() == type)
4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return links_[i];
4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return NULL;
4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Content implementation
4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)Content::Content() {
4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void Content::RegisterJSONConverter(
4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::JSONValueConverter<Content>* converter) {
4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomField(kSrcField, &Content::url_, &GetGURLFromString);
4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterStringField(kTypeField, &Content::mime_type_);
4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AppIcon implementation
4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppIcon::AppIcon() : category_(AppIcon::ICON_UNKNOWN), icon_side_length_(0) {
4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)AppIcon::~AppIcon() {
4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void AppIcon::RegisterJSONConverter(
4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::JSONValueConverter<AppIcon>* converter) {
4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomField<AppIcon::IconCategory>(
4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kInstalledAppIconCategoryField,
4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &AppIcon::category_,
4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &AppIcon::GetIconCategory);
4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomField<int>(kInstalledAppIconSizeField,
4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      &AppIcon::icon_side_length_,
4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                      base::StringToInt);
4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterRepeatedMessage(kLinkField, &AppIcon::links_);
4465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL AppIcon::GetIconURL() const {
4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < links_.size(); ++i) {
4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (links_[i]->type() == Link::LINK_ICON)
4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return links_[i]->href();
4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GURL();
4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool AppIcon::GetIconCategory(const base::StringPiece& category,
4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              AppIcon::IconCategory* result) {
4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kAppIconCategoryMap); i++) {
4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (category == kAppIconCategoryMap[i].category_name) {
4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *result = kAppIconCategoryMap[i].category;
4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Unknown icon category " << category;
4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
4702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// CommonMetadata implementation
4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CommonMetadata::CommonMetadata() {
4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)CommonMetadata::~CommonMetadata() {
4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)template<typename CommonMetadataDescendant>
4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void CommonMetadata::RegisterJSONConverter(
4812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::JSONValueConverter<CommonMetadataDescendant>* converter) {
4822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  converter->RegisterStringField(kETagField, &CommonMetadata::etag_);
4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  converter->template RegisterRepeatedMessage<Author>(
4842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kAuthorField, &CommonMetadata::authors_);
4852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  converter->template RegisterRepeatedMessage<Link>(
4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kLinkField, &CommonMetadata::links_);
4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  converter->template RegisterRepeatedMessage<Category>(
4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kCategoryField, &CommonMetadata::categories_);
4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  converter->template RegisterCustomField<base::Time>(
4902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kUpdatedField, &CommonMetadata::updated_time_, &util::GetTimeFromString);
4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
4942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ResourceEntry implementation
4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
4962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceEntry::ResourceEntry()
4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : kind_(ENTRY_KIND_UNKNOWN),
4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      file_size_(0),
4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      deleted_(false),
5002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      removed_(false),
5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      changestamp_(0) {
5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceEntry::~ResourceEntry() {
5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ResourceEntry::HasFieldPresent(const base::Value* value,
5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    bool* result) {
5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  *result = (value != NULL);
5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ResourceEntry::ParseChangestamp(const base::Value* value,
5142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     int64* result) {
5152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  DCHECK(result);
5162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (!value) {
5172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    *result = 0;
5182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
5192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  }
5202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  std::string string_value;
5222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  if (value->GetAsString(&string_value) &&
5232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      base::StringToInt64(string_value, result))
5242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return true;
5252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return false;
5272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
5282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
5302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceEntry::RegisterJSONConverter(
5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::JSONValueConverter<ResourceEntry>* converter) {
5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Inherit the parent registrations.
5332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommonMetadata::RegisterJSONConverter(converter);
5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterStringField(
5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kResourceIdField, &ResourceEntry::resource_id_);
5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  converter->RegisterStringField(kIDField, &ResourceEntry::id_);
5372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  converter->RegisterStringField(kTitleTField, &ResourceEntry::title_);
5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomField<base::Time>(
5392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kPublishedField, &ResourceEntry::published_time_,
5402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &util::GetTimeFromString);
5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomField<base::Time>(
5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kLastViewedField, &ResourceEntry::last_viewed_time_,
5432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &util::GetTimeFromString);
5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterRepeatedMessage(
5452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kFeedLinkField, &ResourceEntry::resource_links_);
5462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  converter->RegisterNestedField(kContentField, &ResourceEntry::content_);
5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // File properties.  If the resource type is not a normal file, then
5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // that's no problem because those feed must not have these fields
5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // themselves, which does not report errors.
5512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  converter->RegisterStringField(kFileNameField, &ResourceEntry::filename_);
5522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  converter->RegisterStringField(kMD5Field, &ResourceEntry::file_md5_);
5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomField<int64>(
5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kSizeField, &ResourceEntry::file_size_, &base::StringToInt64);
5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterStringField(
5562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kSuggestedFileNameField, &ResourceEntry::suggested_filename_);
5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Deleted are treated as 'trashed' items on web client side. Removed files
5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // are gone for good. We treat both cases as 'deleted' for this client.
5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomValueField<bool>(
5602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kDeletedField, &ResourceEntry::deleted_, &ResourceEntry::HasFieldPresent);
5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomValueField<bool>(
5622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kRemovedField, &ResourceEntry::removed_, &ResourceEntry::HasFieldPresent);
5632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  converter->RegisterCustomValueField<int64>(
5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kChangestampField, &ResourceEntry::changestamp_,
5652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &ResourceEntry::ParseChangestamp);
5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string ResourceEntry::GetHostedDocumentExtension() const {
5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kEntryKindMap); i++) {
5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (kEntryKindMap[i].kind == kind_) {
5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if (kEntryKindMap[i].extension)
5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return std::string(kEntryKindMap[i].extension);
5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else
5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        return std::string();
5755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
5765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
5775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return std::string();
5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
58190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)int ResourceEntry::ClassifyEntryKindByFileExtension(
58290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    const base::FilePath& file_path) {
5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN)
58490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string file_extension = WideToUTF8(file_path.Extension());
5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else
58690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  std::string file_extension = file_path.Extension();
5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif
5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kEntryKindMap); ++i) {
5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const char* document_extension = kEntryKindMap[i].extension;
5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (document_extension && file_extension == document_extension)
59190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      return ClassifyEntryKind(kEntryKindMap[i].kind);
5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
59390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  return 0;
5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)DriveEntryKind ResourceEntry::GetEntryKindFromTerm(
5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& term) {
5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!StartsWithASCII(term, kTermPrefix, false)) {
6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DVLOG(1) << "Unexpected term prefix term " << term;
6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return ENTRY_KIND_UNKNOWN;
6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::string type = term.substr(strlen(kTermPrefix));
6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < arraysize(kEntryKindMap); i++) {
6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (type == kEntryKindMap[i].entry)
6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return kEntryKindMap[i].kind;
6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DVLOG(1) << "Unknown entry type for term " << term << ", type " << type;
6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return ENTRY_KIND_UNKNOWN;
6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
6142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)int ResourceEntry::ClassifyEntryKind(DriveEntryKind kind) {
6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int classes = 0;
6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // All DriveEntryKind members are listed here, so the compiler catches if a
6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // newly added member is missing here.
6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  switch (kind) {
6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ENTRY_KIND_UNKNOWN:
6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Special entries.
6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ENTRY_KIND_ITEM:
6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ENTRY_KIND_SITE:
6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Hosted Google document.
6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ENTRY_KIND_DOCUMENT:
6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ENTRY_KIND_SPREADSHEET:
6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ENTRY_KIND_PRESENTATION:
6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ENTRY_KIND_DRAWING:
6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ENTRY_KIND_TABLE:
6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      classes = KIND_OF_GOOGLE_DOCUMENT | KIND_OF_HOSTED_DOCUMENT;
6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Hosted external application document.
6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ENTRY_KIND_EXTERNAL_APP:
6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      classes = KIND_OF_EXTERNAL_DOCUMENT | KIND_OF_HOSTED_DOCUMENT;
6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Folders, collections.
6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ENTRY_KIND_FOLDER:
6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      classes = KIND_OF_FOLDER;
6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Regular files.
6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ENTRY_KIND_FILE:
6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ENTRY_KIND_PDF:
6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      classes = KIND_OF_FILE;
6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      break;
6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    case ENTRY_KIND_MAX_VALUE:
6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      NOTREACHED();
6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return classes;
6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceEntry::FillRemainingFields() {
6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Set |kind_| and |labels_| based on the |categories_| in the class.
6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // JSONValueConverter does not have the ability to catch an element in a list
6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // based on a predicate.  Thus we need to iterate over |categories_| and
6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // find the elements to set these fields as a post-process.
6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < categories_.size(); ++i) {
6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Category* category = categories_[i];
6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (category->type() == Category::CATEGORY_KIND)
6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kind_ = GetEntryKindFromTerm(category->term());
6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    else if (category->type() == Category::CATEGORY_LABEL)
6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      labels_.push_back(category->label());
6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
6732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<ResourceEntry> ResourceEntry::ExtractAndParse(
6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Value& value) {
6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::DictionaryValue* as_dict = NULL;
6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::DictionaryValue* entry_dict = NULL;
6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value.GetAsDictionary(&as_dict) &&
6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      as_dict->GetDictionary(kEntryField, &entry_dict)) {
6792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ResourceEntry::CreateFrom(*entry_dict);
6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return scoped_ptr<ResourceEntry>();
6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<ResourceEntry> ResourceEntry::CreateFrom(const base::Value& value) {
6862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::JSONValueConverter<ResourceEntry> converter;
6872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceEntry> entry(new ResourceEntry());
6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!converter.Convert(value, entry.get())) {
6892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DVLOG(1) << "Invalid resource entry!";
6902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return scoped_ptr<ResourceEntry>();
6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->FillRemainingFields();
6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return entry.Pass();
6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<ResourceEntry> ResourceEntry::CreateFromFileResource(
6995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const FileResource& file) {
7002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceEntry> entry(new ResourceEntry());
7015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // ResourceEntry
7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->resource_id_ = file.file_id();
7045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->id_ = file.file_id();
7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->kind_ = file.GetKind();
7062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  entry->title_ = file.title();
7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->published_time_ = file.created_date();
7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(kochi): entry->labels_
709c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!file.shared_with_me_date().is_null()) {
710c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    entry->labels_.push_back("shared-with-me");
711c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
712c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
7132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // This should be the url to download the file.
7142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  entry->content_.url_ = file.download_url();
7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->content_.mime_type_ = file.mime_type();
7162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // TODO(kochi): entry->resource_links_
7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // For file entries
7192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  entry->filename_ = file.title();
7202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  entry->suggested_filename_ = file.title();
7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->file_md5_ = file.md5_checksum();
7225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->file_size_ = file.file_size();
7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If file is removed completely, that information is only available in
7255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // ChangeResource, and is reflected in |removed_|. If file is trashed, the
7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // file entry still exists but with its "trashed" label true.
7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->deleted_ = file.labels().is_trashed();
7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  // CommonMetadata
7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->etag_ = file.etag();
7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // entry->authors_
7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // entry->links_.
7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!file.parents().empty()) {
7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Link* link = new Link();
7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    link->type_ = Link::LINK_PARENT;
7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    link->href_ = file.parents()[0]->parent_link();
7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry->links_.push_back(link);
7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!file.self_link().is_empty()) {
7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Link* link = new Link();
7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    link->type_ = Link::LINK_EDIT;
7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    link->href_ = file.self_link();
7435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry->links_.push_back(link);
7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!file.thumbnail_link().is_empty()) {
7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Link* link = new Link();
7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    link->type_ = Link::LINK_THUMBNAIL;
7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    link->href_ = file.thumbnail_link();
7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry->links_.push_back(link);
7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!file.alternate_link().is_empty()) {
7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Link* link = new Link();
7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    link->type_ = Link::LINK_ALTERNATE;
7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    link->href_ = file.alternate_link();
7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry->links_.push_back(link);
7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!file.embed_link().is_empty()) {
7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    Link* link = new Link();
7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    link->type_ = Link::LINK_EMBED;
7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    link->href_ = file.embed_link();
7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry->links_.push_back(link);
7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // entry->categories_
764c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  entry->updated_time_ = file.modified_date();
7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->last_viewed_time_ = file.last_viewed_by_me_date();
7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->FillRemainingFields();
7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return entry.Pass();
7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
7722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<ResourceEntry> ResourceEntry::CreateFromChangeResource(
7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ChangeResource& change) {
7747dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  scoped_ptr<ResourceEntry> entry;
7757dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  if (change.file())
7767dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    entry = CreateFromFileResource(*change.file()).Pass();
7777dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch  else
7787dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch    entry.reset(new ResourceEntry);
7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->resource_id_ = change.file_id();
7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // If |is_deleted()| returns true, the file is removed from Drive.
7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entry->removed_ = change.is_deleted();
78390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)  entry->changestamp_ = change.change_id();
7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return entry.Pass();
7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
7892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)std::string ResourceEntry::GetEntryNodeName() {
7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return kEntryNode;
7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
7942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// ResourceList implementation
7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
7962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceList::ResourceList()
7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : start_index_(0),
7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      items_per_page_(0),
7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      largest_changestamp_(0) {
8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)ResourceList::~ResourceList() {
8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
8062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceList::RegisterJSONConverter(
8072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::JSONValueConverter<ResourceList>* converter) {
8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // inheritance
8092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  CommonMetadata::RegisterJSONConverter(converter);
8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TODO(zelidrag): Once we figure out where these will be used, we should
8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // check for valid start_index_ and items_per_page_ values.
8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomField<int>(
8132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kStartIndexField, &ResourceList::start_index_, &base::StringToInt);
8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomField<int>(
8152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      kItemsPerPageField, &ResourceList::items_per_page_, &base::StringToInt);
8162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  converter->RegisterStringField(kTitleTField, &ResourceList::title_);
8172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  converter->RegisterRepeatedMessage(kEntryField, &ResourceList::entries_);
8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomField<int64>(
8192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)     kLargestChangestampField, &ResourceList::largest_changestamp_,
8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)     &base::StringToInt64);
8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ResourceList::Parse(const base::Value& value) {
8242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::JSONValueConverter<ResourceList> converter;
8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!converter.Convert(value, this)) {
8262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DVLOG(1) << "Invalid resource list!";
8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  ScopedVector<ResourceEntry>::iterator iter = entries_.begin();
8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (iter != entries_.end()) {
8322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    ResourceEntry* entry = (*iter);
8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    entry->FillRemainingFields();
8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++iter;
8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<ResourceList> ResourceList::ExtractAndParse(
8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Value& value) {
8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::DictionaryValue* as_dict = NULL;
8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::DictionaryValue* feed_dict = NULL;
8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (value.GetAsDictionary(&as_dict) &&
8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      as_dict->GetDictionary(kFeedField, &feed_dict)) {
8462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return ResourceList::CreateFrom(*feed_dict);
8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  return scoped_ptr<ResourceList>();
8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
8522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<ResourceList> ResourceList::CreateFrom(const base::Value& value) {
8532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceList> feed(new ResourceList());
8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!feed->Parse(value)) {
8552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    DVLOG(1) << "Invalid resource list!";
8567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return scoped_ptr<ResourceList>();
8575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return feed.Pass();
8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<ResourceList> ResourceList::CreateFromChangeList(
8645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ChangeList& changelist) {
8652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<ResourceList> feed(new ResourceList());
8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int64 largest_changestamp = 0;
8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ScopedVector<ChangeResource>::const_iterator iter =
8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      changelist.items().begin();
8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  while (iter != changelist.items().end()) {
8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const ChangeResource& change = **iter;
8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    largest_changestamp = std::max(largest_changestamp, change.change_id());
8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    feed->entries_.push_back(
8732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        ResourceEntry::CreateFromChangeResource(change).release());
8745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ++iter;
8755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
8765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  feed->largest_changestamp_ = largest_changestamp;
877c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
878c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!changelist.next_link().is_empty()) {
879c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Link* link = new Link();
880c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    link->set_type(Link::LINK_NEXT);
881c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    link->set_href(changelist.next_link());
882c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    feed->links_.push_back(link);
883c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
884c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
885c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return feed.Pass();
886c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}
887c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
888c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// static
889c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)scoped_ptr<ResourceList> ResourceList::CreateFromFileList(
890c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    const FileList& file_list) {
891c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_ptr<ResourceList> feed(new ResourceList);
892c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  const ScopedVector<FileResource>& items = file_list.items();
893c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  for (size_t i = 0; i < items.size(); ++i) {
894c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    feed->entries_.push_back(
895c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        ResourceEntry::CreateFromFileResource(*items[i]).release());
896c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
897c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
898c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  if (!file_list.next_link().is_empty()) {
899c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    Link* link = new Link();
900c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    link->set_type(Link::LINK_NEXT);
901c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    link->set_href(file_list.next_link());
902c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    feed->links_.push_back(link);
903c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  }
904c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return feed.Pass();
9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool ResourceList::GetNextFeedURL(GURL* url) const {
9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(url);
9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (size_t i = 0; i < links_.size(); ++i) {
9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (links_[i]->type() == Link::LINK_NEXT) {
9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      *url = links_[i]->href();
9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return true;
9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return false;
9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void ResourceList::ReleaseEntries(std::vector<ResourceEntry*>* entries) {
9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  entries_.release(entries);
9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// InstalledApp implementation
9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InstalledApp::InstalledApp() : supports_create_(false) {
9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InstalledApp::~InstalledApp() {
9305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)InstalledApp::IconList InstalledApp::GetIconsForCategory(
9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    AppIcon::IconCategory category) const {
9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  IconList result;
9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ScopedVector<AppIcon>::const_iterator icon_iter = app_icons_.begin();
9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       icon_iter != app_icons_.end(); ++icon_iter) {
9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if ((*icon_iter)->category() != category)
9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    GURL icon_url = (*icon_iter)->GetIconURL();
9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (icon_url.is_empty())
9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      continue;
9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    result.push_back(std::make_pair((*icon_iter)->icon_side_length(),
9445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                    icon_url));
9455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Return a sorted list, smallest to largest.
9485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  std::sort(result.begin(), result.end(), SortBySize);
9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return result;
9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)GURL InstalledApp::GetProductUrl() const {
9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  for (ScopedVector<Link>::const_iterator it = links_.begin();
9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)       it != links_.end(); ++it) {
9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const Link* link = *it;
9565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (link->type() == Link::LINK_PRODUCT)
9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return link->href();
9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return GURL();
9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InstalledApp::GetValueString(const base::Value* value,
9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                  std::string* result) {
9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::DictionaryValue* dict = NULL;
9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!value->GetAsDictionary(&dict))
9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!dict->GetString(kTField, result))
9705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
9715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
9735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InstalledApp::RegisterJSONConverter(
9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    base::JSONValueConverter<InstalledApp>* converter) {
9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterRepeatedMessage(kInstalledAppIconField,
9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                     &InstalledApp::app_icons_);
9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterStringField(kInstalledAppIdField,
9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 &InstalledApp::app_id_);
9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterStringField(kInstalledAppNameField,
9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 &InstalledApp::app_name_);
9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterStringField(kInstalledAppObjectTypeField,
9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 &InstalledApp::object_type_);
9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomField<bool>(kInstalledAppSupportsCreateField,
9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       &InstalledApp::supports_create_,
9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                       &GetBoolFromString);
9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterRepeatedCustomValue(kInstalledAppPrimaryMimeTypeField,
9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         &InstalledApp::primary_mimetypes_,
9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         &GetValueString);
9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterRepeatedCustomValue(kInstalledAppSecondaryMimeTypeField,
9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         &InstalledApp::secondary_mimetypes_,
9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         &GetValueString);
9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterRepeatedCustomValue(kInstalledAppPrimaryFileExtensionField,
9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         &InstalledApp::primary_extensions_,
9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                         &GetValueString);
9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterRepeatedCustomValue(
9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kInstalledAppSecondaryFileExtensionField,
10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &InstalledApp::secondary_extensions_,
10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &GetValueString);
10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterRepeatedMessage(kLinkField, &InstalledApp::links_);
10035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)////////////////////////////////////////////////////////////////////////////////
10062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// AccountMetadata implementation
10075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AccountMetadata::AccountMetadata()
10095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : quota_bytes_total_(0),
10105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      quota_bytes_used_(0),
10115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      largest_changestamp_(0) {
10125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)AccountMetadata::~AccountMetadata() {
10155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
10182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void AccountMetadata::RegisterJSONConverter(
10192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    base::JSONValueConverter<AccountMetadata>* converter) {
10205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomField<int64>(
10215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kQuotaBytesTotalField,
10222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &AccountMetadata::quota_bytes_total_,
10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &base::StringToInt64);
10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomField<int64>(
10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kQuotaBytesUsedField,
10262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &AccountMetadata::quota_bytes_used_,
10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &base::StringToInt64);
10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterCustomField<int64>(
10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      kLargestChangestampField,
10302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      &AccountMetadata::largest_changestamp_,
10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      &base::StringToInt64);
10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  converter->RegisterRepeatedMessage(kInstalledAppField,
10332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                                     &AccountMetadata::installed_apps_);
10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
10372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)scoped_ptr<AccountMetadata> AccountMetadata::CreateFrom(
10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const base::Value& value) {
10392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<AccountMetadata> metadata(new AccountMetadata());
10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::DictionaryValue* dictionary = NULL;
10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const base::Value* entry = NULL;
10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!value.GetAsDictionary(&dictionary) ||
10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      !dictionary->Get(kEntryField, &entry) ||
10442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      !metadata->Parse(*entry)) {
10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Unable to create: Invalid account metadata feed!";
10467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return scoped_ptr<AccountMetadata>();
10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  return metadata.Pass();
10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool AccountMetadata::Parse(const base::Value& value) {
10532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  base::JSONValueConverter<AccountMetadata> converter;
10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!converter.Convert(value, this)) {
10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    LOG(ERROR) << "Unable to parse: Invalid account metadata feed!";
10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return false;
10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
10585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return true;
10595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
10605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace google_apis
1062