OLD | NEW |
| (Empty) |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 | |
5 #include "chrome/browser/google_apis/drive_api_parser.h" | |
6 | |
7 #include <algorithm> | |
8 | |
9 #include "base/basictypes.h" | |
10 #include "base/files/file_path.h" | |
11 #include "base/json/json_value_converter.h" | |
12 #include "base/memory/scoped_ptr.h" | |
13 #include "base/strings/string_number_conversions.h" | |
14 #include "base/strings/string_piece.h" | |
15 #include "base/strings/string_util.h" | |
16 #include "base/values.h" | |
17 #include "chrome/browser/google_apis/time_util.h" | |
18 | |
19 using base::Value; | |
20 using base::DictionaryValue; | |
21 using base::ListValue; | |
22 | |
23 namespace google_apis { | |
24 | |
25 namespace { | |
26 | |
27 bool CreateFileResourceFromValue(const base::Value* value, | |
28 scoped_ptr<FileResource>* file) { | |
29 *file = FileResource::CreateFrom(*value); | |
30 return !!*file; | |
31 } | |
32 | |
33 // Converts |url_string| to |result|. Always returns true to be used | |
34 // for JSONValueConverter::RegisterCustomField method. | |
35 // TODO(mukai): make it return false in case of invalid |url_string|. | |
36 bool GetGURLFromString(const base::StringPiece& url_string, GURL* result) { | |
37 *result = GURL(url_string.as_string()); | |
38 return true; | |
39 } | |
40 | |
41 // Converts |value| to |result|. The key of |value| is app_id, and its value | |
42 // is URL to open the resource on the web app. | |
43 bool GetOpenWithLinksFromDictionaryValue( | |
44 const base::Value* value, | |
45 std::vector<FileResource::OpenWithLink>* result) { | |
46 DCHECK(value); | |
47 DCHECK(result); | |
48 | |
49 const base::DictionaryValue* dictionary_value; | |
50 if (!value->GetAsDictionary(&dictionary_value)) | |
51 return false; | |
52 | |
53 result->reserve(dictionary_value->size()); | |
54 for (DictionaryValue::Iterator iter(*dictionary_value); | |
55 !iter.IsAtEnd(); iter.Advance()) { | |
56 std::string string_value; | |
57 if (!iter.value().GetAsString(&string_value)) | |
58 return false; | |
59 | |
60 FileResource::OpenWithLink open_with_link; | |
61 open_with_link.app_id = iter.key(); | |
62 open_with_link.open_url = GURL(string_value); | |
63 result->push_back(open_with_link); | |
64 } | |
65 | |
66 return true; | |
67 } | |
68 | |
69 // Drive v2 API JSON names. | |
70 | |
71 // Definition order follows the order of documentation in | |
72 // https://developers.google.com/drive/v2/reference/ | |
73 | |
74 // Common | |
75 const char kKind[] = "kind"; | |
76 const char kId[] = "id"; | |
77 const char kETag[] = "etag"; | |
78 const char kSelfLink[] = "selfLink"; | |
79 const char kItems[] = "items"; | |
80 const char kLargestChangeId[] = "largestChangeId"; | |
81 | |
82 // About Resource | |
83 // https://developers.google.com/drive/v2/reference/about | |
84 const char kAboutKind[] = "drive#about"; | |
85 const char kQuotaBytesTotal[] = "quotaBytesTotal"; | |
86 const char kQuotaBytesUsed[] = "quotaBytesUsed"; | |
87 const char kRootFolderId[] = "rootFolderId"; | |
88 | |
89 // App Icon | |
90 // https://developers.google.com/drive/v2/reference/apps | |
91 const char kCategory[] = "category"; | |
92 const char kSize[] = "size"; | |
93 const char kIconUrl[] = "iconUrl"; | |
94 | |
95 // Apps Resource | |
96 // https://developers.google.com/drive/v2/reference/apps | |
97 const char kAppKind[] = "drive#app"; | |
98 const char kName[] = "name"; | |
99 const char kObjectType[] = "objectType"; | |
100 const char kSupportsCreate[] = "supportsCreate"; | |
101 const char kSupportsImport[] = "supportsImport"; | |
102 const char kInstalled[] = "installed"; | |
103 const char kAuthorized[] = "authorized"; | |
104 const char kProductUrl[] = "productUrl"; | |
105 const char kPrimaryMimeTypes[] = "primaryMimeTypes"; | |
106 const char kSecondaryMimeTypes[] = "secondaryMimeTypes"; | |
107 const char kPrimaryFileExtensions[] = "primaryFileExtensions"; | |
108 const char kSecondaryFileExtensions[] = "secondaryFileExtensions"; | |
109 const char kIcons[] = "icons"; | |
110 | |
111 // Apps List | |
112 // https://developers.google.com/drive/v2/reference/apps/list | |
113 const char kAppListKind[] = "drive#appList"; | |
114 | |
115 // Parent Resource | |
116 // https://developers.google.com/drive/v2/reference/parents | |
117 const char kParentReferenceKind[] = "drive#parentReference"; | |
118 const char kParentLink[] = "parentLink"; | |
119 const char kIsRoot[] = "isRoot"; | |
120 | |
121 // File Resource | |
122 // https://developers.google.com/drive/v2/reference/files | |
123 const char kFileKind[] = "drive#file"; | |
124 const char kTitle[] = "title"; | |
125 const char kMimeType[] = "mimeType"; | |
126 const char kCreatedDate[] = "createdDate"; | |
127 const char kModifiedDate[] = "modifiedDate"; | |
128 const char kModifiedByMeDate[] = "modifiedByMeDate"; | |
129 const char kLastViewedByMeDate[] = "lastViewedByMeDate"; | |
130 const char kSharedWithMeDate[] = "sharedWithMeDate"; | |
131 const char kDownloadUrl[] = "downloadUrl"; | |
132 const char kFileExtension[] = "fileExtension"; | |
133 const char kMd5Checksum[] = "md5Checksum"; | |
134 const char kFileSize[] = "fileSize"; | |
135 const char kAlternateLink[] = "alternateLink"; | |
136 const char kEmbedLink[] = "embedLink"; | |
137 const char kParents[] = "parents"; | |
138 const char kThumbnailLink[] = "thumbnailLink"; | |
139 const char kWebContentLink[] = "webContentLink"; | |
140 const char kOpenWithLinks[] = "openWithLinks"; | |
141 const char kLabels[] = "labels"; | |
142 const char kImageMediaMetadata[] = "imageMediaMetadata"; | |
143 // These 5 flags are defined under |labels|. | |
144 const char kLabelStarred[] = "starred"; | |
145 const char kLabelHidden[] = "hidden"; | |
146 const char kLabelTrashed[] = "trashed"; | |
147 const char kLabelRestricted[] = "restricted"; | |
148 const char kLabelViewed[] = "viewed"; | |
149 // These 3 flags are defined under |imageMediaMetadata|. | |
150 const char kImageMediaMetadataWidth[] = "width"; | |
151 const char kImageMediaMetadataHeight[] = "height"; | |
152 const char kImageMediaMetadataRotation[] = "rotation"; | |
153 | |
154 const char kDriveFolderMimeType[] = "application/vnd.google-apps.folder"; | |
155 | |
156 // Files List | |
157 // https://developers.google.com/drive/v2/reference/files/list | |
158 const char kFileListKind[] = "drive#fileList"; | |
159 const char kNextPageToken[] = "nextPageToken"; | |
160 const char kNextLink[] = "nextLink"; | |
161 | |
162 // Change Resource | |
163 // https://developers.google.com/drive/v2/reference/changes | |
164 const char kChangeKind[] = "drive#change"; | |
165 const char kFileId[] = "fileId"; | |
166 const char kDeleted[] = "deleted"; | |
167 const char kFile[] = "file"; | |
168 | |
169 // Changes List | |
170 // https://developers.google.com/drive/v2/reference/changes/list | |
171 const char kChangeListKind[] = "drive#changeList"; | |
172 | |
173 // Maps category name to enum IconCategory. | |
174 struct AppIconCategoryMap { | |
175 DriveAppIcon::IconCategory category; | |
176 const char* category_name; | |
177 }; | |
178 | |
179 const AppIconCategoryMap kAppIconCategoryMap[] = { | |
180 { DriveAppIcon::DOCUMENT, "document" }, | |
181 { DriveAppIcon::APPLICATION, "application" }, | |
182 { DriveAppIcon::SHARED_DOCUMENT, "documentShared" }, | |
183 }; | |
184 | |
185 // Checks if the JSON is expected kind. In Drive API, JSON data structure has | |
186 // |kind| property which denotes the type of the structure (e.g. "drive#file"). | |
187 bool IsResourceKindExpected(const base::Value& value, | |
188 const std::string& expected_kind) { | |
189 const base::DictionaryValue* as_dict = NULL; | |
190 std::string kind; | |
191 return value.GetAsDictionary(&as_dict) && | |
192 as_dict->HasKey(kKind) && | |
193 as_dict->GetString(kKind, &kind) && | |
194 kind == expected_kind; | |
195 } | |
196 | |
197 } // namespace | |
198 | |
199 //////////////////////////////////////////////////////////////////////////////// | |
200 // AboutResource implementation | |
201 | |
202 AboutResource::AboutResource() | |
203 : largest_change_id_(0), | |
204 quota_bytes_total_(0), | |
205 quota_bytes_used_(0) {} | |
206 | |
207 AboutResource::~AboutResource() {} | |
208 | |
209 // static | |
210 scoped_ptr<AboutResource> AboutResource::CreateFrom(const base::Value& value) { | |
211 scoped_ptr<AboutResource> resource(new AboutResource()); | |
212 if (!IsResourceKindExpected(value, kAboutKind) || !resource->Parse(value)) { | |
213 LOG(ERROR) << "Unable to create: Invalid About resource JSON!"; | |
214 return scoped_ptr<AboutResource>(); | |
215 } | |
216 return resource.Pass(); | |
217 } | |
218 | |
219 // static | |
220 void AboutResource::RegisterJSONConverter( | |
221 base::JSONValueConverter<AboutResource>* converter) { | |
222 converter->RegisterCustomField<int64>(kLargestChangeId, | |
223 &AboutResource::largest_change_id_, | |
224 &base::StringToInt64); | |
225 converter->RegisterCustomField<int64>(kQuotaBytesTotal, | |
226 &AboutResource::quota_bytes_total_, | |
227 &base::StringToInt64); | |
228 converter->RegisterCustomField<int64>(kQuotaBytesUsed, | |
229 &AboutResource::quota_bytes_used_, | |
230 &base::StringToInt64); | |
231 converter->RegisterStringField(kRootFolderId, | |
232 &AboutResource::root_folder_id_); | |
233 } | |
234 | |
235 bool AboutResource::Parse(const base::Value& value) { | |
236 base::JSONValueConverter<AboutResource> converter; | |
237 if (!converter.Convert(value, this)) { | |
238 LOG(ERROR) << "Unable to parse: Invalid About resource JSON!"; | |
239 return false; | |
240 } | |
241 return true; | |
242 } | |
243 | |
244 //////////////////////////////////////////////////////////////////////////////// | |
245 // DriveAppIcon implementation | |
246 | |
247 DriveAppIcon::DriveAppIcon() : category_(UNKNOWN), icon_side_length_(0) {} | |
248 | |
249 DriveAppIcon::~DriveAppIcon() {} | |
250 | |
251 // static | |
252 void DriveAppIcon::RegisterJSONConverter( | |
253 base::JSONValueConverter<DriveAppIcon>* converter) { | |
254 converter->RegisterCustomField<IconCategory>( | |
255 kCategory, | |
256 &DriveAppIcon::category_, | |
257 &DriveAppIcon::GetIconCategory); | |
258 converter->RegisterIntField(kSize, &DriveAppIcon::icon_side_length_); | |
259 converter->RegisterCustomField<GURL>(kIconUrl, | |
260 &DriveAppIcon::icon_url_, | |
261 GetGURLFromString); | |
262 } | |
263 | |
264 // static | |
265 scoped_ptr<DriveAppIcon> DriveAppIcon::CreateFrom(const base::Value& value) { | |
266 scoped_ptr<DriveAppIcon> resource(new DriveAppIcon()); | |
267 if (!resource->Parse(value)) { | |
268 LOG(ERROR) << "Unable to create: Invalid DriveAppIcon JSON!"; | |
269 return scoped_ptr<DriveAppIcon>(); | |
270 } | |
271 return resource.Pass(); | |
272 } | |
273 | |
274 bool DriveAppIcon::Parse(const base::Value& value) { | |
275 base::JSONValueConverter<DriveAppIcon> converter; | |
276 if (!converter.Convert(value, this)) { | |
277 LOG(ERROR) << "Unable to parse: Invalid DriveAppIcon"; | |
278 return false; | |
279 } | |
280 return true; | |
281 } | |
282 | |
283 // static | |
284 bool DriveAppIcon::GetIconCategory(const base::StringPiece& category, | |
285 DriveAppIcon::IconCategory* result) { | |
286 for (size_t i = 0; i < arraysize(kAppIconCategoryMap); i++) { | |
287 if (category == kAppIconCategoryMap[i].category_name) { | |
288 *result = kAppIconCategoryMap[i].category; | |
289 return true; | |
290 } | |
291 } | |
292 DVLOG(1) << "Unknown icon category " << category; | |
293 return false; | |
294 } | |
295 | |
296 //////////////////////////////////////////////////////////////////////////////// | |
297 // AppResource implementation | |
298 | |
299 AppResource::AppResource() | |
300 : supports_create_(false), | |
301 supports_import_(false), | |
302 installed_(false), | |
303 authorized_(false) { | |
304 } | |
305 | |
306 AppResource::~AppResource() {} | |
307 | |
308 // static | |
309 void AppResource::RegisterJSONConverter( | |
310 base::JSONValueConverter<AppResource>* converter) { | |
311 converter->RegisterStringField(kId, &AppResource::application_id_); | |
312 converter->RegisterStringField(kName, &AppResource::name_); | |
313 converter->RegisterStringField(kObjectType, &AppResource::object_type_); | |
314 converter->RegisterBoolField(kSupportsCreate, &AppResource::supports_create_); | |
315 converter->RegisterBoolField(kSupportsImport, &AppResource::supports_import_); | |
316 converter->RegisterBoolField(kInstalled, &AppResource::installed_); | |
317 converter->RegisterBoolField(kAuthorized, &AppResource::authorized_); | |
318 converter->RegisterCustomField<GURL>(kProductUrl, | |
319 &AppResource::product_url_, | |
320 GetGURLFromString); | |
321 converter->RegisterRepeatedString(kPrimaryMimeTypes, | |
322 &AppResource::primary_mimetypes_); | |
323 converter->RegisterRepeatedString(kSecondaryMimeTypes, | |
324 &AppResource::secondary_mimetypes_); | |
325 converter->RegisterRepeatedString(kPrimaryFileExtensions, | |
326 &AppResource::primary_file_extensions_); | |
327 converter->RegisterRepeatedString(kSecondaryFileExtensions, | |
328 &AppResource::secondary_file_extensions_); | |
329 converter->RegisterRepeatedMessage(kIcons, &AppResource::icons_); | |
330 } | |
331 | |
332 // static | |
333 scoped_ptr<AppResource> AppResource::CreateFrom(const base::Value& value) { | |
334 scoped_ptr<AppResource> resource(new AppResource()); | |
335 if (!IsResourceKindExpected(value, kAppKind) || !resource->Parse(value)) { | |
336 LOG(ERROR) << "Unable to create: Invalid AppResource JSON!"; | |
337 return scoped_ptr<AppResource>(); | |
338 } | |
339 return resource.Pass(); | |
340 } | |
341 | |
342 bool AppResource::Parse(const base::Value& value) { | |
343 base::JSONValueConverter<AppResource> converter; | |
344 if (!converter.Convert(value, this)) { | |
345 LOG(ERROR) << "Unable to parse: Invalid AppResource"; | |
346 return false; | |
347 } | |
348 return true; | |
349 } | |
350 | |
351 //////////////////////////////////////////////////////////////////////////////// | |
352 // AppList implementation | |
353 | |
354 AppList::AppList() {} | |
355 | |
356 AppList::~AppList() {} | |
357 | |
358 // static | |
359 void AppList::RegisterJSONConverter( | |
360 base::JSONValueConverter<AppList>* converter) { | |
361 converter->RegisterStringField(kETag, &AppList::etag_); | |
362 converter->RegisterRepeatedMessage<AppResource>(kItems, | |
363 &AppList::items_); | |
364 } | |
365 | |
366 // static | |
367 scoped_ptr<AppList> AppList::CreateFrom(const base::Value& value) { | |
368 scoped_ptr<AppList> resource(new AppList()); | |
369 if (!IsResourceKindExpected(value, kAppListKind) || !resource->Parse(value)) { | |
370 LOG(ERROR) << "Unable to create: Invalid AppList JSON!"; | |
371 return scoped_ptr<AppList>(); | |
372 } | |
373 return resource.Pass(); | |
374 } | |
375 | |
376 bool AppList::Parse(const base::Value& value) { | |
377 base::JSONValueConverter<AppList> converter; | |
378 if (!converter.Convert(value, this)) { | |
379 LOG(ERROR) << "Unable to parse: Invalid AppList"; | |
380 return false; | |
381 } | |
382 return true; | |
383 } | |
384 | |
385 //////////////////////////////////////////////////////////////////////////////// | |
386 // ParentReference implementation | |
387 | |
388 ParentReference::ParentReference() : is_root_(false) {} | |
389 | |
390 ParentReference::~ParentReference() {} | |
391 | |
392 // static | |
393 void ParentReference::RegisterJSONConverter( | |
394 base::JSONValueConverter<ParentReference>* converter) { | |
395 converter->RegisterStringField(kId, &ParentReference::file_id_); | |
396 converter->RegisterCustomField<GURL>(kParentLink, | |
397 &ParentReference::parent_link_, | |
398 GetGURLFromString); | |
399 converter->RegisterBoolField(kIsRoot, &ParentReference::is_root_); | |
400 } | |
401 | |
402 // static | |
403 scoped_ptr<ParentReference> | |
404 ParentReference::CreateFrom(const base::Value& value) { | |
405 scoped_ptr<ParentReference> reference(new ParentReference()); | |
406 if (!IsResourceKindExpected(value, kParentReferenceKind) || | |
407 !reference->Parse(value)) { | |
408 LOG(ERROR) << "Unable to create: Invalid ParentRefernce JSON!"; | |
409 return scoped_ptr<ParentReference>(); | |
410 } | |
411 return reference.Pass(); | |
412 } | |
413 | |
414 bool ParentReference::Parse(const base::Value& value) { | |
415 base::JSONValueConverter<ParentReference> converter; | |
416 if (!converter.Convert(value, this)) { | |
417 LOG(ERROR) << "Unable to parse: Invalid ParentReference"; | |
418 return false; | |
419 } | |
420 return true; | |
421 } | |
422 | |
423 //////////////////////////////////////////////////////////////////////////////// | |
424 // FileResource implementation | |
425 | |
426 FileResource::FileResource() : file_size_(0) {} | |
427 | |
428 FileResource::~FileResource() {} | |
429 | |
430 // static | |
431 void FileResource::RegisterJSONConverter( | |
432 base::JSONValueConverter<FileResource>* converter) { | |
433 converter->RegisterStringField(kId, &FileResource::file_id_); | |
434 converter->RegisterStringField(kETag, &FileResource::etag_); | |
435 converter->RegisterCustomField<GURL>(kSelfLink, | |
436 &FileResource::self_link_, | |
437 GetGURLFromString); | |
438 converter->RegisterStringField(kTitle, &FileResource::title_); | |
439 converter->RegisterStringField(kMimeType, &FileResource::mime_type_); | |
440 converter->RegisterNestedField(kLabels, &FileResource::labels_); | |
441 converter->RegisterNestedField(kImageMediaMetadata, | |
442 &FileResource::image_media_metadata_); | |
443 converter->RegisterCustomField<base::Time>( | |
444 kCreatedDate, | |
445 &FileResource::created_date_, | |
446 &util::GetTimeFromString); | |
447 converter->RegisterCustomField<base::Time>( | |
448 kModifiedDate, | |
449 &FileResource::modified_date_, | |
450 &util::GetTimeFromString); | |
451 converter->RegisterCustomField<base::Time>( | |
452 kModifiedByMeDate, | |
453 &FileResource::modified_by_me_date_, | |
454 &util::GetTimeFromString); | |
455 converter->RegisterCustomField<base::Time>( | |
456 kLastViewedByMeDate, | |
457 &FileResource::last_viewed_by_me_date_, | |
458 &util::GetTimeFromString); | |
459 converter->RegisterCustomField<base::Time>( | |
460 kSharedWithMeDate, | |
461 &FileResource::shared_with_me_date_, | |
462 &util::GetTimeFromString); | |
463 converter->RegisterCustomField<GURL>(kDownloadUrl, | |
464 &FileResource::download_url_, | |
465 GetGURLFromString); | |
466 converter->RegisterStringField(kFileExtension, | |
467 &FileResource::file_extension_); | |
468 converter->RegisterStringField(kMd5Checksum, &FileResource::md5_checksum_); | |
469 converter->RegisterCustomField<int64>(kFileSize, | |
470 &FileResource::file_size_, | |
471 &base::StringToInt64); | |
472 converter->RegisterCustomField<GURL>(kAlternateLink, | |
473 &FileResource::alternate_link_, | |
474 GetGURLFromString); | |
475 converter->RegisterCustomField<GURL>(kEmbedLink, | |
476 &FileResource::embed_link_, | |
477 GetGURLFromString); | |
478 converter->RegisterRepeatedMessage<ParentReference>(kParents, | |
479 &FileResource::parents_); | |
480 converter->RegisterCustomField<GURL>(kThumbnailLink, | |
481 &FileResource::thumbnail_link_, | |
482 GetGURLFromString); | |
483 converter->RegisterCustomField<GURL>(kWebContentLink, | |
484 &FileResource::web_content_link_, | |
485 GetGURLFromString); | |
486 converter->RegisterCustomValueField<std::vector<OpenWithLink> >( | |
487 kOpenWithLinks, | |
488 &FileResource::open_with_links_, | |
489 GetOpenWithLinksFromDictionaryValue); | |
490 } | |
491 | |
492 // static | |
493 scoped_ptr<FileResource> FileResource::CreateFrom(const base::Value& value) { | |
494 scoped_ptr<FileResource> resource(new FileResource()); | |
495 if (!IsResourceKindExpected(value, kFileKind) || !resource->Parse(value)) { | |
496 LOG(ERROR) << "Unable to create: Invalid FileResource JSON!"; | |
497 return scoped_ptr<FileResource>(); | |
498 } | |
499 return resource.Pass(); | |
500 } | |
501 | |
502 bool FileResource::IsDirectory() const { | |
503 return mime_type_ == kDriveFolderMimeType; | |
504 } | |
505 | |
506 bool FileResource::Parse(const base::Value& value) { | |
507 base::JSONValueConverter<FileResource> converter; | |
508 if (!converter.Convert(value, this)) { | |
509 LOG(ERROR) << "Unable to parse: Invalid FileResource"; | |
510 return false; | |
511 } | |
512 return true; | |
513 } | |
514 | |
515 //////////////////////////////////////////////////////////////////////////////// | |
516 // FileList implementation | |
517 | |
518 FileList::FileList() {} | |
519 | |
520 FileList::~FileList() {} | |
521 | |
522 // static | |
523 void FileList::RegisterJSONConverter( | |
524 base::JSONValueConverter<FileList>* converter) { | |
525 converter->RegisterStringField(kETag, &FileList::etag_); | |
526 converter->RegisterStringField(kNextPageToken, &FileList::next_page_token_); | |
527 converter->RegisterCustomField<GURL>(kNextLink, | |
528 &FileList::next_link_, | |
529 GetGURLFromString); | |
530 converter->RegisterRepeatedMessage<FileResource>(kItems, | |
531 &FileList::items_); | |
532 } | |
533 | |
534 // static | |
535 bool FileList::HasFileListKind(const base::Value& value) { | |
536 return IsResourceKindExpected(value, kFileListKind); | |
537 } | |
538 | |
539 // static | |
540 scoped_ptr<FileList> FileList::CreateFrom(const base::Value& value) { | |
541 scoped_ptr<FileList> resource(new FileList()); | |
542 if (!HasFileListKind(value) || !resource->Parse(value)) { | |
543 LOG(ERROR) << "Unable to create: Invalid FileList JSON!"; | |
544 return scoped_ptr<FileList>(); | |
545 } | |
546 return resource.Pass(); | |
547 } | |
548 | |
549 bool FileList::Parse(const base::Value& value) { | |
550 base::JSONValueConverter<FileList> converter; | |
551 if (!converter.Convert(value, this)) { | |
552 LOG(ERROR) << "Unable to parse: Invalid FileList"; | |
553 return false; | |
554 } | |
555 return true; | |
556 } | |
557 | |
558 //////////////////////////////////////////////////////////////////////////////// | |
559 // ChangeResource implementation | |
560 | |
561 ChangeResource::ChangeResource() : change_id_(0), deleted_(false) {} | |
562 | |
563 ChangeResource::~ChangeResource() {} | |
564 | |
565 // static | |
566 void ChangeResource::RegisterJSONConverter( | |
567 base::JSONValueConverter<ChangeResource>* converter) { | |
568 converter->RegisterCustomField<int64>(kId, | |
569 &ChangeResource::change_id_, | |
570 &base::StringToInt64); | |
571 converter->RegisterStringField(kFileId, &ChangeResource::file_id_); | |
572 converter->RegisterBoolField(kDeleted, &ChangeResource::deleted_); | |
573 converter->RegisterCustomValueField(kFile, &ChangeResource::file_, | |
574 &CreateFileResourceFromValue); | |
575 } | |
576 | |
577 // static | |
578 scoped_ptr<ChangeResource> | |
579 ChangeResource::CreateFrom(const base::Value& value) { | |
580 scoped_ptr<ChangeResource> resource(new ChangeResource()); | |
581 if (!IsResourceKindExpected(value, kChangeKind) || !resource->Parse(value)) { | |
582 LOG(ERROR) << "Unable to create: Invalid ChangeResource JSON!"; | |
583 return scoped_ptr<ChangeResource>(); | |
584 } | |
585 return resource.Pass(); | |
586 } | |
587 | |
588 bool ChangeResource::Parse(const base::Value& value) { | |
589 base::JSONValueConverter<ChangeResource> converter; | |
590 if (!converter.Convert(value, this)) { | |
591 LOG(ERROR) << "Unable to parse: Invalid ChangeResource"; | |
592 return false; | |
593 } | |
594 return true; | |
595 } | |
596 | |
597 //////////////////////////////////////////////////////////////////////////////// | |
598 // ChangeList implementation | |
599 | |
600 ChangeList::ChangeList() : largest_change_id_(0) {} | |
601 | |
602 ChangeList::~ChangeList() {} | |
603 | |
604 // static | |
605 void ChangeList::RegisterJSONConverter( | |
606 base::JSONValueConverter<ChangeList>* converter) { | |
607 converter->RegisterStringField(kETag, &ChangeList::etag_); | |
608 converter->RegisterStringField(kNextPageToken, &ChangeList::next_page_token_); | |
609 converter->RegisterCustomField<GURL>(kNextLink, | |
610 &ChangeList::next_link_, | |
611 GetGURLFromString); | |
612 converter->RegisterCustomField<int64>(kLargestChangeId, | |
613 &ChangeList::largest_change_id_, | |
614 &base::StringToInt64); | |
615 converter->RegisterRepeatedMessage<ChangeResource>(kItems, | |
616 &ChangeList::items_); | |
617 } | |
618 | |
619 // static | |
620 bool ChangeList::HasChangeListKind(const base::Value& value) { | |
621 return IsResourceKindExpected(value, kChangeListKind); | |
622 } | |
623 | |
624 // static | |
625 scoped_ptr<ChangeList> ChangeList::CreateFrom(const base::Value& value) { | |
626 scoped_ptr<ChangeList> resource(new ChangeList()); | |
627 if (!HasChangeListKind(value) || !resource->Parse(value)) { | |
628 LOG(ERROR) << "Unable to create: Invalid ChangeList JSON!"; | |
629 return scoped_ptr<ChangeList>(); | |
630 } | |
631 return resource.Pass(); | |
632 } | |
633 | |
634 bool ChangeList::Parse(const base::Value& value) { | |
635 base::JSONValueConverter<ChangeList> converter; | |
636 if (!converter.Convert(value, this)) { | |
637 LOG(ERROR) << "Unable to parse: Invalid ChangeList"; | |
638 return false; | |
639 } | |
640 return true; | |
641 } | |
642 | |
643 | |
644 //////////////////////////////////////////////////////////////////////////////// | |
645 // FileLabels implementation | |
646 | |
647 FileLabels::FileLabels() | |
648 : starred_(false), | |
649 hidden_(false), | |
650 trashed_(false), | |
651 restricted_(false), | |
652 viewed_(false) {} | |
653 | |
654 FileLabels::~FileLabels() {} | |
655 | |
656 // static | |
657 void FileLabels::RegisterJSONConverter( | |
658 base::JSONValueConverter<FileLabels>* converter) { | |
659 converter->RegisterBoolField(kLabelStarred, &FileLabels::starred_); | |
660 converter->RegisterBoolField(kLabelHidden, &FileLabels::hidden_); | |
661 converter->RegisterBoolField(kLabelTrashed, &FileLabels::trashed_); | |
662 converter->RegisterBoolField(kLabelRestricted, &FileLabels::restricted_); | |
663 converter->RegisterBoolField(kLabelViewed, &FileLabels::viewed_); | |
664 } | |
665 | |
666 // static | |
667 scoped_ptr<FileLabels> FileLabels::CreateFrom(const base::Value& value) { | |
668 scoped_ptr<FileLabels> resource(new FileLabels()); | |
669 if (!resource->Parse(value)) { | |
670 LOG(ERROR) << "Unable to create: Invalid FileLabels JSON!"; | |
671 return scoped_ptr<FileLabels>(); | |
672 } | |
673 return resource.Pass(); | |
674 } | |
675 | |
676 bool FileLabels::Parse(const base::Value& value) { | |
677 base::JSONValueConverter<FileLabels> converter; | |
678 if (!converter.Convert(value, this)) { | |
679 LOG(ERROR) << "Unable to parse: Invalid FileLabels."; | |
680 return false; | |
681 } | |
682 return true; | |
683 } | |
684 | |
685 //////////////////////////////////////////////////////////////////////////////// | |
686 // ImageMediaMetadata implementation | |
687 | |
688 ImageMediaMetadata::ImageMediaMetadata() | |
689 : width_(-1), | |
690 height_(-1), | |
691 rotation_(-1) {} | |
692 | |
693 ImageMediaMetadata::~ImageMediaMetadata() {} | |
694 | |
695 // static | |
696 void ImageMediaMetadata::RegisterJSONConverter( | |
697 base::JSONValueConverter<ImageMediaMetadata>* converter) { | |
698 converter->RegisterIntField(kImageMediaMetadataWidth, | |
699 &ImageMediaMetadata::width_); | |
700 converter->RegisterIntField(kImageMediaMetadataHeight, | |
701 &ImageMediaMetadata::height_); | |
702 converter->RegisterIntField(kImageMediaMetadataRotation, | |
703 &ImageMediaMetadata::rotation_); | |
704 } | |
705 | |
706 // static | |
707 scoped_ptr<ImageMediaMetadata> ImageMediaMetadata::CreateFrom( | |
708 const base::Value& value) { | |
709 scoped_ptr<ImageMediaMetadata> resource(new ImageMediaMetadata()); | |
710 if (!resource->Parse(value)) { | |
711 LOG(ERROR) << "Unable to create: Invalid ImageMediaMetadata JSON!"; | |
712 return scoped_ptr<ImageMediaMetadata>(); | |
713 } | |
714 return resource.Pass(); | |
715 } | |
716 | |
717 bool ImageMediaMetadata::Parse(const base::Value& value) { | |
718 return true; | |
719 base::JSONValueConverter<ImageMediaMetadata> converter; | |
720 if (!converter.Convert(value, this)) { | |
721 LOG(ERROR) << "Unable to parse: Invalid ImageMediaMetadata."; | |
722 return false; | |
723 } | |
724 return true; | |
725 } | |
726 | |
727 } // namespace google_apis | |
OLD | NEW |