person.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
1// Copyright 2013 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/ui/app_list/search/people/person.h"
6
7#include <vector>
8
9#include "base/strings/string_number_conversions.h"
10#include "base/values.h"
11
12namespace {
13
14const char kKeyId[] = "person.id";
15const char kKeyNames[] = "person.names";
16const char kKeyDisplayName[] = "displayName";
17const char kKeyEmails[] = "person.emails";
18const char kKeyEmailValue[] = "value";
19const char kKeyInteractionRank[] = "person.sortKeys.interactionRank";
20const char kKeyImages[] = "person.images";
21const char kKeyUrl[] = "url";
22const char kKeyOwnerId[] = "person.metadata.ownerId";
23
24// Finds a list in a dictionary, specified by list_key, then returns the
25// first value associated with item_key in the first dictionary in that list.
26// So, for this dictionary,
27// { key_random: value1,
28//   list_key: [ { random_key: value2,
29//                 item_key: TARGET_VALUE,
30//                 another_random_key: value3 } ],
31//   another_key: value4 }
32//
33//  we'll return TARGET_VALUE.
34//
35// The reason for this (seemingly) strange behavior is that several of our
36// results are going to be in this form and we need to repeat this operation
37// to parse them.
38std::string GetTargetValue(const base::DictionaryValue& dict,
39                           const char list_key[],
40                           const char item_key[]) {
41  const base::ListValue* list;
42  if (!dict.GetList(list_key, &list) || !list)
43    return std::string();
44
45  base::ListValue::const_iterator it = list->begin();
46  if (it == list->end())
47    return std::string();
48
49  base::DictionaryValue* sub_dict;
50  if (!(*it)->GetAsDictionary(&sub_dict) || !sub_dict)
51    return std::string();
52
53  std::string value;
54  if (!sub_dict->GetString(item_key, &value))
55    return std::string();
56
57  return value;
58}
59
60}  // namespace
61
62
63namespace app_list {
64
65// static
66scoped_ptr<Person> Person::Create(const base::DictionaryValue& dict) {
67  scoped_ptr<Person> person(new Person());
68
69  // Person id's.
70  if (!dict.GetString(kKeyId, &person->id) ||
71      !dict.GetString(kKeyOwnerId, &person->owner_id)) {
72    person.reset();
73    return person.Pass();
74  }
75
76  // Interaction rank.
77  std::string interaction_rank_string;
78  if (!dict.GetString(kKeyInteractionRank, &interaction_rank_string) ||
79      !base::StringToDouble(
80            interaction_rank_string, &person->interaction_rank)) {
81    person.reset();
82    return person.Pass();
83  }
84
85  person->display_name = GetTargetValue(dict, kKeyNames, kKeyDisplayName);
86  person->email = GetTargetValue(dict, kKeyEmails, kKeyEmailValue);
87  person->image_url = GURL(GetTargetValue(dict, kKeyImages, kKeyUrl));
88
89  // If any of our values are invalid, null out our result.
90  if (person->id.empty() ||
91      person->owner_id.empty() ||
92      person->display_name.empty() ||
93      person->email.empty() ||
94      !person->image_url.is_valid() ||
95      person->interaction_rank == 0.0) {
96    person.reset();
97  }
98
99  return person.Pass();
100}
101
102Person::Person() : interaction_rank(0.0) {
103}
104
105Person::~Person() {
106}
107
108scoped_ptr<Person> Person::Duplicate() {
109  scoped_ptr<Person> person(new Person());
110  *person = *this;
111  return person.Pass();
112}
113
114}  // namespace app_list
115