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 "cloud_print/gcp20/prototype/cloud_print_response_parser.h" 6 7 #include "base/json/json_reader.h" 8 #include "base/json/json_writer.h" 9 #include "base/logging.h" 10 #include "base/values.h" 11 12 namespace cloud_print_response_parser { 13 14 Job::Job() { 15 } 16 17 Job::~Job() { 18 } 19 20 // Parses json base::Value to base::DictionaryValue. 21 // If |success| value in JSON dictionary is |false| then |message| will 22 // contain |message| from the JSON dictionary. 23 // Returns |true| if no parsing error occurred. 24 bool GetJsonDictinaryAndCheckSuccess(base::Value* json, 25 std::string* error_description, 26 bool* json_success, 27 std::string* message, 28 base::DictionaryValue** dictionary) { 29 base::DictionaryValue* response_dictionary = NULL; 30 if (!json || !json->GetAsDictionary(&response_dictionary)) { 31 *error_description = "No JSON dictionary response received."; 32 return false; 33 } 34 35 bool response_json_success = false; 36 if (!response_dictionary->GetBoolean("success", &response_json_success)) { 37 *error_description = "Cannot parse success state."; 38 return false; 39 } 40 41 if (!response_json_success) { 42 std::string response_message; 43 if (!response_dictionary->GetString("message", &response_message)) { 44 *error_description = "Cannot parse message from response."; 45 return false; 46 } 47 *message = response_message; 48 } 49 50 *json_success = response_json_success; 51 *dictionary = response_dictionary; 52 return true; 53 } 54 55 bool ParseRegisterStartResponse(const std::string& response, 56 std::string* error_description, 57 std::string* polling_url, 58 std::string* registration_token, 59 std::string* complete_invite_url, 60 std::string* device_id) { 61 scoped_ptr<base::Value> json(base::JSONReader::Read(response)); 62 base::DictionaryValue* response_dictionary = NULL; 63 bool json_success; 64 std::string message; 65 if (!GetJsonDictinaryAndCheckSuccess(json.get(), error_description, 66 &json_success, &message, 67 &response_dictionary)) { 68 return false; 69 } 70 if (!json_success) { 71 *error_description = message; 72 return false; 73 } 74 75 std::string response_registration_token; 76 if (!response_dictionary->GetString("registration_token", 77 &response_registration_token)) { 78 *error_description = "No registration_token specified."; 79 return false; 80 } 81 82 std::string response_complete_invite_url; 83 if (!response_dictionary->GetString("complete_invite_url", 84 &response_complete_invite_url)) { 85 *error_description = "No complete_invite_url specified."; 86 return false; 87 } 88 89 std::string response_polling_url; 90 if (!response_dictionary->GetString("polling_url", &response_polling_url)) { 91 *error_description = "No polling_url specified."; 92 return false; 93 } 94 95 base::ListValue* list = NULL; 96 if (!response_dictionary->GetList("printers", &list)) { 97 *error_description = "No printers list specified."; 98 return false; 99 } 100 101 base::DictionaryValue* printer = NULL; 102 if (!list->GetDictionary(0, &printer)) { 103 *error_description = "Printers list is empty or printer is not dictionary."; 104 return false; 105 } 106 107 std::string id; 108 if (!printer->GetString("id", &id)) { 109 *error_description = "No id specified."; 110 return false; 111 } 112 113 if (id.empty()) { 114 *error_description = "id is empty."; 115 return false; 116 } 117 118 *polling_url = response_polling_url; 119 *registration_token = response_registration_token; 120 *complete_invite_url = response_complete_invite_url; 121 *device_id = id; 122 return true; 123 } 124 125 bool ParseRegisterCompleteResponse(const std::string& response, 126 std::string* error_description, 127 std::string* authorization_code, 128 std::string* xmpp_jid) { 129 scoped_ptr<base::Value> json(base::JSONReader::Read(response)); 130 base::DictionaryValue* response_dictionary = NULL; 131 bool json_success; 132 std::string message; 133 if (!GetJsonDictinaryAndCheckSuccess(json.get(), error_description, 134 &json_success, &message, 135 &response_dictionary)) { 136 return false; 137 } 138 if (!json_success) { 139 *error_description = message; 140 return false; 141 } 142 143 std::string response_authorization_code; 144 if (!response_dictionary->GetString("authorization_code", 145 &response_authorization_code)) { 146 *error_description = "Cannot parse authorization_code."; 147 return false; 148 } 149 150 std::string response_xmpp_jid; 151 if (!response_dictionary->GetString("xmpp_jid", &response_xmpp_jid)) { 152 *error_description = "Cannot parse xmpp jid."; 153 return false; 154 } 155 156 *authorization_code = response_authorization_code; 157 *xmpp_jid = response_xmpp_jid; 158 return true; 159 } 160 161 bool ParseFetchResponse(const std::string& response, 162 std::string* error_description, 163 std::vector<Job>* list) { 164 scoped_ptr<base::Value> json(base::JSONReader::Read(response)); 165 base::DictionaryValue* response_dictionary = NULL; 166 bool json_success; 167 std::string message; 168 if (!GetJsonDictinaryAndCheckSuccess(json.get(), error_description, 169 &json_success, &message, 170 &response_dictionary)) { 171 return false; 172 } 173 174 if (!json_success) { // Let's suppose we have no jobs to proceed. 175 list->clear(); 176 return true; 177 } 178 179 base::ListValue* jobs = NULL; 180 if (!response_dictionary->GetList("jobs", &jobs)) { 181 *error_description = "Cannot parse jobs list."; 182 return false; 183 } 184 185 std::vector<Job> job_list(jobs->GetSize()); 186 for (size_t idx = 0; idx < job_list.size(); ++idx) { 187 base::DictionaryValue* job = NULL; 188 jobs->GetDictionary(idx, &job); 189 if (!job->GetString("id", &job_list[idx].job_id) || 190 !job->GetString("createTime", &job_list[idx].create_time) || 191 !job->GetString("fileUrl", &job_list[idx].file_url) || 192 !job->GetString("ticketUrl", &job_list[idx].ticket_url) || 193 !job->GetString("title", &job_list[idx].title)) { 194 *error_description = "Cannot parse job info."; 195 return false; 196 } 197 } 198 199 *list = job_list; 200 201 return true; 202 } 203 204 } // namespace cloud_print_response_parser 205 206