1// Copyright (C) 2013 Google Inc. 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14 15#include <libaddressinput/localization.h> 16 17#include <libaddressinput/address_data.h> 18#include <libaddressinput/address_field.h> 19#include <libaddressinput/address_problem.h> 20 21#include <cassert> 22#include <cstddef> 23#include <string> 24 25#include "grit.h" 26#include "region_data_constants.h" 27#include "rule.h" 28#include "util/string_split.h" 29#include "util/string_util.h" 30 31namespace { 32 33void PushBackUrl(std::vector<std::string>& parameters, const std::string url) { 34 // TODO: HTML-escape the "url". 35 parameters.push_back("<a href=\"" + url + "\">"); 36 parameters.push_back("</a>"); 37} 38 39} // namespace 40 41namespace i18n { 42namespace addressinput { 43 44namespace { 45 46#include "en_messages.cc" 47 48std::string GetEnglishString(int message_id) { 49 const char* str = GetString(message_id); 50 return str != NULL ? std::string(str) : std::string(); 51} 52 53} // namespace 54 55Localization::Localization() : get_string_(&GetEnglishString) {} 56 57Localization::~Localization() {} 58 59std::string Localization::GetString(int message_id) const { 60 return get_string_(message_id); 61} 62 63std::string Localization::GetErrorMessage(const AddressData& address, 64 AddressField field, 65 AddressProblem problem, 66 bool enable_examples, 67 bool enable_links) const { 68 if (field == POSTAL_CODE) { 69 Rule rule; 70 rule.CopyFrom(Rule::GetDefault()); 71 std::string postal_code_example, post_service_url; 72 if (rule.ParseSerializedRule( 73 RegionDataConstants::GetRegionData(address.region_code))) { 74 if (enable_examples) { 75 std::vector<std::string> examples_list; 76 SplitString(rule.GetPostalCodeExample(), ',', &examples_list); 77 if (!examples_list.empty()) { 78 postal_code_example = examples_list.front(); 79 } 80 } 81 if (enable_links) { 82 post_service_url = rule.GetPostServiceUrl(); 83 } 84 } else { 85 assert(false); 86 } 87 // If we can't parse the serialized rule |uses_postal_code_as_label| will be 88 // determined from the default rule. 89 bool uses_postal_code_as_label = 90 rule.GetPostalCodeNameMessageId() == 91 IDS_LIBADDRESSINPUT_POSTAL_CODE_LABEL; 92 return GetErrorMessageForPostalCode(address, problem, 93 uses_postal_code_as_label, 94 postal_code_example, post_service_url); 95 } else { 96 if (problem == MISSING_REQUIRED_FIELD) { 97 return get_string_(IDS_LIBADDRESSINPUT_MISSING_REQUIRED_FIELD); 98 } else if (problem == UNKNOWN_VALUE) { 99 std::vector<std::string> parameters; 100 if (AddressData::IsRepeatedFieldValue(field)) { 101 std::vector<std::string> values = address.GetRepeatedFieldValue(field); 102 assert(!values.empty()); 103 parameters.push_back(values.front()); 104 } else { 105 parameters.push_back(address.GetFieldValue(field)); 106 } 107 return DoReplaceStringPlaceholders( 108 get_string_(IDS_LIBADDRESSINPUT_UNKNOWN_VALUE), parameters); 109 } else if (problem == USES_P_O_BOX) { 110 return get_string_(IDS_LIBADDRESSINPUT_PO_BOX_FORBIDDEN_VALUE); 111 } else { 112 // Keep the default under "else" so the compiler helps us check that all 113 // handled cases return and don't fall through. 114 assert(false); 115 return ""; 116 } 117 } 118} 119 120void Localization::SetGetter(std::string (*getter)(int)) { 121 assert(getter != NULL); 122 get_string_ = getter; 123} 124 125std::string Localization::GetErrorMessageForPostalCode( 126 const AddressData& address, 127 AddressProblem problem, 128 bool uses_postal_code_as_label, 129 std::string postal_code_example, 130 std::string post_service_url) const { 131 int message_id; 132 std::vector<std::string> parameters; 133 if (problem == MISSING_REQUIRED_FIELD) { 134 if (!postal_code_example.empty() && !post_service_url.empty()) { 135 message_id = uses_postal_code_as_label ? 136 IDS_LIBADDRESSINPUT_MISSING_REQUIRED_POSTAL_CODE_EXAMPLE_AND_URL : 137 IDS_LIBADDRESSINPUT_MISSING_REQUIRED_ZIP_CODE_EXAMPLE_AND_URL; 138 parameters.push_back(postal_code_example); 139 PushBackUrl(parameters, post_service_url); 140 } else if (!postal_code_example.empty()) { 141 message_id = uses_postal_code_as_label ? 142 IDS_LIBADDRESSINPUT_MISSING_REQUIRED_POSTAL_CODE_EXAMPLE : 143 IDS_LIBADDRESSINPUT_MISSING_REQUIRED_ZIP_CODE_EXAMPLE ; 144 parameters.push_back(postal_code_example); 145 } else { 146 message_id = IDS_LIBADDRESSINPUT_MISSING_REQUIRED_FIELD; 147 } 148 return DoReplaceStringPlaceholders(get_string_(message_id), parameters); 149 } else if (problem == INVALID_FORMAT) { 150 if (!postal_code_example.empty() && !post_service_url.empty()) { 151 message_id = uses_postal_code_as_label ? 152 IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_POSTAL_CODE_EXAMPLE_AND_URL : 153 IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_ZIP_CODE_EXAMPLE_AND_URL; 154 parameters.push_back(postal_code_example); 155 PushBackUrl(parameters, post_service_url); 156 } else if (!postal_code_example.empty()) { 157 message_id = uses_postal_code_as_label ? 158 IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_POSTAL_CODE_EXAMPLE : 159 IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_ZIP_CODE_EXAMPLE; 160 parameters.push_back(postal_code_example); 161 } else { 162 message_id = uses_postal_code_as_label ? 163 IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_POSTAL_CODE : 164 IDS_LIBADDRESSINPUT_UNRECOGNIZED_FORMAT_ZIP; 165 } 166 return DoReplaceStringPlaceholders(get_string_(message_id), parameters); 167 } else if (problem == MISMATCHING_VALUE) { 168 if (!post_service_url.empty()) { 169 message_id = uses_postal_code_as_label ? 170 IDS_LIBADDRESSINPUT_MISMATCHING_VALUE_POSTAL_CODE_URL : 171 IDS_LIBADDRESSINPUT_MISMATCHING_VALUE_ZIP_URL; 172 PushBackUrl(parameters, post_service_url); 173 } else { 174 message_id = uses_postal_code_as_label ? 175 IDS_LIBADDRESSINPUT_MISMATCHING_VALUE_POSTAL_CODE : 176 IDS_LIBADDRESSINPUT_MISMATCHING_VALUE_ZIP; 177 } 178 return DoReplaceStringPlaceholders(get_string_(message_id), parameters); 179 } else { 180 // Keep the default under "else" so the compiler helps us check that all 181 // handled cases return and don't fall through. 182 assert(false); 183 return ""; 184 } 185} 186 187} // namespace addressinput 188} // namespace i18n 189