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