1a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Copyright (C) 2013 Google Inc.
2a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//
3a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Licensed under the Apache License, Version 2.0 (the "License");
4a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// you may not use this file except in compliance with the License.
5a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// You may obtain a copy of the License at
6a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//
7a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// http://www.apache.org/licenses/LICENSE-2.0
8a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)//
9a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// Unless required by applicable law or agreed to in writing, software
10a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// distributed under the License is distributed on an "AS IS" BASIS,
11a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// See the License for the specific language governing permissions and
13a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)// limitations under the License.
14a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
15a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "rule.h"
16a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
17a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <libaddressinput/address_field.h>
18a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <libaddressinput/util/scoped_ptr.h>
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <map>
21a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <string>
22a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include <utility>
23a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
24a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "address_field_util.h"
25a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "grit.h"
26a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "messages.h"
27a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)#include "util/json.h"
28d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)#include "util/string_split.h"
29a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
30a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace i18n {
31a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace addressinput {
32a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
33a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)namespace {
34a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
35a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)typedef std::map<std::string, int> NameMessageIdMap;
36a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
37a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char kAdminAreaNameTypeKey[] = "state_name_type";
38a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char kFormatKey[] = "fmt";
39d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)const char kLanguageKey[] = "lang";
40d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)const char kLanguagesKey[] = "languages";
41a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const char kPostalCodeNameTypeKey[] = "zip_name_type";
42d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)const char kSubKeysKey[] = "sub_keys";
43d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
44d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// Used as a separator in a list of items. For example, the list of supported
45d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)// languages can be "de~fr~it".
46d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)const char kSeparator = '~';
47a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
48a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)NameMessageIdMap InitAdminAreaMessageIds() {
49a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  NameMessageIdMap message_ids;
50a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  message_ids.insert(std::make_pair(
51a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "area", IDS_LIBADDRESSINPUT_I18N_AREA));
52a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  message_ids.insert(std::make_pair(
53a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "county", IDS_LIBADDRESSINPUT_I18N_COUNTY_LABEL));
54a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  message_ids.insert(std::make_pair(
55a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "department", IDS_LIBADDRESSINPUT_I18N_DEPARTMENT));
56a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  message_ids.insert(std::make_pair(
57a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "district", IDS_LIBADDRESSINPUT_I18N_DEPENDENT_LOCALITY_LABEL));
58a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  message_ids.insert(std::make_pair(
59a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "do_si", IDS_LIBADDRESSINPUT_I18N_DO_SI));
60a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  message_ids.insert(std::make_pair(
61a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "emirate", IDS_LIBADDRESSINPUT_I18N_EMIRATE));
62a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  message_ids.insert(std::make_pair(
63a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "island", IDS_LIBADDRESSINPUT_I18N_ISLAND));
64a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  message_ids.insert(std::make_pair(
65a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "parish", IDS_LIBADDRESSINPUT_I18N_PARISH));
66a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  message_ids.insert(std::make_pair(
67a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "prefecture", IDS_LIBADDRESSINPUT_I18N_PREFECTURE));
68a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  message_ids.insert(std::make_pair(
69a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "province", IDS_LIBADDRESSINPUT_I18N_PROVINCE));
70a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  message_ids.insert(std::make_pair(
71a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "state", IDS_LIBADDRESSINPUT_I18N_STATE_LABEL));
72a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return message_ids;
73a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
74a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
75a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const NameMessageIdMap& GetAdminAreaMessageIds() {
76a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static const NameMessageIdMap kAdminAreaMessageIds(InitAdminAreaMessageIds());
77a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return kAdminAreaMessageIds;
78a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
79a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
80a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)NameMessageIdMap InitPostalCodeMessageIds() {
81a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  NameMessageIdMap message_ids;
82a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  message_ids.insert(std::make_pair(
83a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "postal", IDS_LIBADDRESSINPUT_I18N_POSTAL_CODE_LABEL));
84a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  message_ids.insert(std::make_pair(
85a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      "zip", IDS_LIBADDRESSINPUT_I18N_ZIP_CODE_LABEL));
86a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return message_ids;
87a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
88a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
89a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)const NameMessageIdMap& GetPostalCodeMessageIds() {
90a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  static const NameMessageIdMap kPostalCodeMessageIds(
91a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      InitPostalCodeMessageIds());
92a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return kPostalCodeMessageIds;
93a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
94a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
95a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)int GetMessageIdFromName(const std::string& name,
96a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                         const NameMessageIdMap& message_ids) {
97a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  NameMessageIdMap::const_iterator it = message_ids.find(name);
98a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return it != message_ids.end() ? it->second : INVALID_MESSAGE_ID;
99a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
100a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
101a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace
102a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
103a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)Rule::Rule()
104a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    : format_(),
105d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      sub_keys_(),
106d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      languages_(),
107d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)      language_(),
108a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      admin_area_name_message_id_(INVALID_MESSAGE_ID),
109a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)      postal_code_name_message_id_(INVALID_MESSAGE_ID) {}
110a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
111a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)Rule::~Rule() {}
112a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
113a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)void Rule::CopyFrom(const Rule& rule) {
114a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  format_ = rule.format_;
115d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  sub_keys_ = rule.sub_keys_;
116d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  languages_ = rule.languages_;
117d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  language_ = rule.language_;
118a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  admin_area_name_message_id_ = rule.admin_area_name_message_id_;
119a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  postal_code_name_message_id_ = rule.postal_code_name_message_id_;
120a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
121a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
122a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)bool Rule::ParseSerializedRule(const std::string& serialized_rule) {
123a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  scoped_ptr<Json> json(Json::Build());
124a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (!json->ParseObject(serialized_rule)) {
125a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    return false;
126a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
127a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
128a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (json->HasStringValueForKey(kFormatKey)) {
129a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    ParseAddressFieldsFormat(json->GetStringValueForKey(kFormatKey), &format_);
130a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
131a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
132d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  if (json->HasStringValueForKey(kSubKeysKey)) {
133d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    SplitString(
134d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)        json->GetStringValueForKey(kSubKeysKey), kSeparator, &sub_keys_);
135d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  }
136d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
137d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  if (json->HasStringValueForKey(kLanguagesKey)) {
138d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    SplitString(
139d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)        json->GetStringValueForKey(kLanguagesKey), kSeparator, &languages_);
140d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  }
141d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
142d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  if (json->HasStringValueForKey(kLanguageKey)) {
143d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)    language_ = json->GetStringValueForKey(kLanguageKey);
144d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)  }
145d57369da7c6519fef57db42085f7b42d4c8845c1Torne (Richard Coles)
146a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (json->HasStringValueForKey(kAdminAreaNameTypeKey)) {
147a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    admin_area_name_message_id_ =
148a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        GetMessageIdFromName(json->GetStringValueForKey(kAdminAreaNameTypeKey),
149a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             GetAdminAreaMessageIds());
150a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
151a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
152a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  if (json->HasStringValueForKey(kPostalCodeNameTypeKey)) {
153a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    postal_code_name_message_id_ =
154a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)        GetMessageIdFromName(json->GetStringValueForKey(kPostalCodeNameTypeKey),
155a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)                             GetPostalCodeMessageIds());
156a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  }
157a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
158a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)  return true;
159a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}
160a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)
161a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace addressinput
162a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)}  // namespace i18n
163