1 /* 2 * Copyright (C) 2009 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 package android.pim.vcard; 17 18 import java.util.HashMap; 19 import java.util.Map; 20 21 /** 22 * The class representing VCard related configurations. Useful static methods are not in this class 23 * but in VCardUtils. 24 */ 25 public class VCardConfig { 26 // TODO: may be better to make the instance of this available and stop using static methods and 27 // one integer. 28 29 /* package */ static final int LOG_LEVEL_NONE = 0; 30 /* package */ static final int LOG_LEVEL_PERFORMANCE_MEASUREMENT = 0x1; 31 /* package */ static final int LOG_LEVEL_SHOW_WARNING = 0x2; 32 /* package */ static final int LOG_LEVEL_VERBOSE = 33 LOG_LEVEL_PERFORMANCE_MEASUREMENT | LOG_LEVEL_SHOW_WARNING; 34 35 /* package */ static final int LOG_LEVEL = LOG_LEVEL_NONE; 36 37 // Assumes that "iso-8859-1" is able to map "all" 8bit characters to some unicode and 38 // decode the unicode to the original charset. If not, this setting will cause some bug. 39 public static final String DEFAULT_CHARSET = "iso-8859-1"; 40 41 // TODO: make the other codes use this flag 42 public static final boolean IGNORE_CASE_EXCEPT_VALUE = true; 43 44 private static final int FLAG_V21 = 0; 45 private static final int FLAG_V30 = 1; 46 47 // 0x2 is reserved for the future use ... 48 49 public static final int NAME_ORDER_DEFAULT = 0; 50 public static final int NAME_ORDER_EUROPE = 0x4; 51 public static final int NAME_ORDER_JAPANESE = 0x8; 52 private static final int NAME_ORDER_MASK = 0xC; 53 54 // 0x10 is reserved for safety 55 56 private static final int FLAG_CHARSET_UTF8 = 0; 57 private static final int FLAG_CHARSET_SHIFT_JIS = 0x20; 58 59 /** 60 * The flag indicating the vCard composer will add some "X-" properties used only in Android 61 * when the formal vCard specification does not have appropriate fields for that data. 62 * 63 * For example, Android accepts nickname information while vCard 2.1 does not. 64 * When this flag is on, vCard composer emits alternative "X-" property (like "X-NICKNAME") 65 * instead of just dropping it. 66 * 67 * vCard parser code automatically parses the field emitted even when this flag is off. 68 * 69 * Note that this flag does not assure all the information must be hold in the emitted vCard. 70 */ 71 private static final int FLAG_USE_ANDROID_PROPERTY = 0x80000000; 72 73 /** 74 * The flag indicating the vCard composer will add some "X-" properties seen in the 75 * vCard data emitted by the other softwares/devices when the formal vCard specification 76 * does not have appropriate field(s) for that data. 77 * 78 * One example is X-PHONETIC-FIRST-NAME/X-PHONETIC-MIDDLE-NAME/X-PHONETIC-LAST-NAME, which are 79 * for phonetic name (how the name is pronounced), seen in the vCard emitted by some other 80 * non-Android devices/softwares. We chose to enable the vCard composer to use those 81 * defact properties since they are also useful for Android devices. 82 * 83 * Note for developers: only "X-" properties should be added with this flag. vCard 2.1/3.0 84 * allows any kind of "X-" properties but does not allow non-"X-" properties (except IANA tokens 85 * in vCard 3.0). Some external parsers may get confused with non-valid, non-"X-" properties. 86 */ 87 private static final int FLAG_USE_DEFACT_PROPERTY = 0x40000000; 88 89 /** 90 * The flag indicating some specific dialect seen in vcard of DoCoMo (one of Japanese 91 * mobile careers) should be used. This flag does not include any other information like 92 * that "the vCard is for Japanese". So it is "possible" that "the vCard should have DoCoMo's 93 * dialect but the name order should be European", but it is not recommended. 94 */ 95 private static final int FLAG_DOCOMO = 0x20000000; 96 97 /** 98 * The flag indicating the vCard composer use Quoted-Printable toward even "primary" types. 99 * In this context, "primary" types means "N", "FN", etc. which are usually "not" encoded 100 * into Quoted-Printable format in external exporters. 101 * This flag is useful when some target importer does not accept "primary" property values 102 * without Quoted-Printable encoding. 103 * 104 * @hide Temporaly made public. We don't strictly define "primary", so we may change the 105 * behavior around this flag in the future. Do not use this flag without any reason. 106 */ 107 public static final int FLAG_USE_QP_TO_PRIMARY_PROPERTIES = 0x10000000; 108 109 // VCard types 110 111 /** 112 * General vCard format with the version 2.1. Uses UTF-8 for the charset. 113 * When composing a vCard entry, the US convension will be used. 114 * 115 * e.g. The order of the display name would be "Prefix Given Middle Family Suffix", 116 * while in Japan, it should be "Prefix Family Middle Given Suffix". 117 */ 118 public static final int VCARD_TYPE_V21_GENERIC = 119 (FLAG_V21 | NAME_ORDER_DEFAULT | FLAG_CHARSET_UTF8 | 120 FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); 121 122 /* package */ static String VCARD_TYPE_V21_GENERIC_STR = "v21_generic"; 123 124 /** 125 * General vCard format with the version 3.0. Uses UTF-8 for the charset. 126 * 127 * Note that this type is not fully implemented, so probably some bugs remain both in 128 * parsing and composing. 129 * 130 * TODO: implement this type correctly. 131 */ 132 public static final int VCARD_TYPE_V30_GENERIC = 133 (FLAG_V30 | NAME_ORDER_DEFAULT | FLAG_CHARSET_UTF8 | 134 FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); 135 136 /* package */ static final String VCARD_TYPE_V30_GENERIC_STR = "v30_generic"; 137 138 /** 139 * General vCard format with the version 2.1 with some Europe convension. Uses Utf-8. 140 * Currently, only name order is considered ("Prefix Middle Given Family Suffix") 141 */ 142 public static final int VCARD_TYPE_V21_EUROPE = 143 (FLAG_V21 | NAME_ORDER_EUROPE | FLAG_CHARSET_UTF8 | 144 FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); 145 146 /* package */ static final String VCARD_TYPE_V21_EUROPE_STR = "v21_europe"; 147 148 /** 149 * General vCard format with the version 3.0 with some Europe convension. Uses UTF-8 150 */ 151 public static final int VCARD_TYPE_V30_EUROPE = 152 (FLAG_V30 | NAME_ORDER_EUROPE | FLAG_CHARSET_UTF8 | 153 FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); 154 155 /* package */ static final String VCARD_TYPE_V30_EUROPE_STR = "v30_europe"; 156 157 /** 158 * vCard 2.1 format for miscellaneous Japanese devices. Shift_Jis is used for 159 * parsing/composing the vCard data. 160 */ 161 public static final int VCARD_TYPE_V21_JAPANESE = 162 (FLAG_V21 | NAME_ORDER_JAPANESE | FLAG_CHARSET_SHIFT_JIS | 163 FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); 164 165 /* package */ static final String VCARD_TYPE_V21_JAPANESE_STR = "v21_japanese"; 166 167 /** 168 * vCard 2.1 format for miscellaneous Japanese devices, using UTF-8 as default charset. 169 */ 170 public static final int VCARD_TYPE_V21_JAPANESE_UTF8 = 171 (FLAG_V21 | NAME_ORDER_JAPANESE | FLAG_CHARSET_UTF8 | 172 FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); 173 174 /* package */ static final String VCARD_TYPE_V21_JAPANESE_UTF8_STR = "v21_japanese_utf8"; 175 176 /** 177 * vCard format for miscellaneous Japanese devices, using Shift_Jis for 178 * parsing/composing the vCard data. 179 */ 180 public static final int VCARD_TYPE_V30_JAPANESE = 181 (FLAG_V30 | NAME_ORDER_JAPANESE | FLAG_CHARSET_SHIFT_JIS | 182 FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); 183 184 /* package */ static final String VCARD_TYPE_V30_JAPANESE_STR = "v30_japanese"; 185 186 /** 187 * vCard 3.0 format for miscellaneous Japanese devices, using UTF-8 as default charset. 188 */ 189 public static final int VCARD_TYPE_V30_JAPANESE_UTF8 = 190 (FLAG_V30 | NAME_ORDER_JAPANESE | FLAG_CHARSET_UTF8 | 191 FLAG_USE_DEFACT_PROPERTY | FLAG_USE_ANDROID_PROPERTY); 192 193 /* package */ static final String VCARD_TYPE_V30_JAPANESE_UTF8_STR = "v30_japanese_utf8"; 194 195 /** 196 * VCard format used in DoCoMo, which is one of Japanese mobile phone careers. 197 * Base version is vCard 2.1, but the data has several DoCoMo-specific convensions. 198 * No Android-specific property nor defact property is included. 199 */ 200 public static final int VCARD_TYPE_DOCOMO = 201 (FLAG_V21 | NAME_ORDER_JAPANESE | FLAG_CHARSET_SHIFT_JIS | FLAG_DOCOMO); 202 203 private static final String VCARD_TYPE_DOCOMO_STR = "docomo"; 204 205 public static int VCARD_TYPE_DEFAULT = VCARD_TYPE_V21_GENERIC; 206 207 private static final Map<String, Integer> VCARD_TYPES_MAP; 208 209 static { 210 VCARD_TYPES_MAP = new HashMap<String, Integer>(); VCARD_TYPES_MAP.put(VCARD_TYPE_V21_GENERIC_STR, VCARD_TYPE_V21_GENERIC)211 VCARD_TYPES_MAP.put(VCARD_TYPE_V21_GENERIC_STR, VCARD_TYPE_V21_GENERIC); VCARD_TYPES_MAP.put(VCARD_TYPE_V30_GENERIC_STR, VCARD_TYPE_V30_GENERIC)212 VCARD_TYPES_MAP.put(VCARD_TYPE_V30_GENERIC_STR, VCARD_TYPE_V30_GENERIC); VCARD_TYPES_MAP.put(VCARD_TYPE_V21_EUROPE_STR, VCARD_TYPE_V21_EUROPE)213 VCARD_TYPES_MAP.put(VCARD_TYPE_V21_EUROPE_STR, VCARD_TYPE_V21_EUROPE); VCARD_TYPES_MAP.put(VCARD_TYPE_V30_EUROPE_STR, VCARD_TYPE_V30_EUROPE)214 VCARD_TYPES_MAP.put(VCARD_TYPE_V30_EUROPE_STR, VCARD_TYPE_V30_EUROPE); VCARD_TYPES_MAP.put(VCARD_TYPE_V21_JAPANESE_STR, VCARD_TYPE_V21_JAPANESE)215 VCARD_TYPES_MAP.put(VCARD_TYPE_V21_JAPANESE_STR, VCARD_TYPE_V21_JAPANESE); VCARD_TYPES_MAP.put(VCARD_TYPE_V21_JAPANESE_UTF8_STR, VCARD_TYPE_V21_JAPANESE_UTF8)216 VCARD_TYPES_MAP.put(VCARD_TYPE_V21_JAPANESE_UTF8_STR, VCARD_TYPE_V21_JAPANESE_UTF8); VCARD_TYPES_MAP.put(VCARD_TYPE_V30_JAPANESE_STR, VCARD_TYPE_V30_JAPANESE)217 VCARD_TYPES_MAP.put(VCARD_TYPE_V30_JAPANESE_STR, VCARD_TYPE_V30_JAPANESE); VCARD_TYPES_MAP.put(VCARD_TYPE_V30_JAPANESE_UTF8_STR, VCARD_TYPE_V30_JAPANESE_UTF8)218 VCARD_TYPES_MAP.put(VCARD_TYPE_V30_JAPANESE_UTF8_STR, VCARD_TYPE_V30_JAPANESE_UTF8); VCARD_TYPES_MAP.put(VCARD_TYPE_DOCOMO_STR, VCARD_TYPE_DOCOMO)219 VCARD_TYPES_MAP.put(VCARD_TYPE_DOCOMO_STR, VCARD_TYPE_DOCOMO); 220 } 221 getVCardTypeFromString(String vcardTypeString)222 public static int getVCardTypeFromString(String vcardTypeString) { 223 String loweredKey = vcardTypeString.toLowerCase(); 224 if (VCARD_TYPES_MAP.containsKey(loweredKey)) { 225 return VCARD_TYPES_MAP.get(loweredKey); 226 } else { 227 // XXX: should return the value indicating the input is invalid? 228 return VCARD_TYPE_DEFAULT; 229 } 230 } 231 isV30(int vcardType)232 public static boolean isV30(int vcardType) { 233 return ((vcardType & FLAG_V30) != 0); 234 } 235 usesQuotedPrintable(int vcardType)236 public static boolean usesQuotedPrintable(int vcardType) { 237 return !isV30(vcardType); 238 } 239 isDoCoMo(int vcardType)240 public static boolean isDoCoMo(int vcardType) { 241 return ((vcardType & FLAG_DOCOMO) != 0); 242 } 243 244 /** 245 * @return true if the device is Japanese and some Japanese convension is 246 * applied to creating "formatted" something like FORMATTED_ADDRESS. 247 */ isJapaneseDevice(int vcardType)248 public static boolean isJapaneseDevice(int vcardType) { 249 return ((vcardType == VCARD_TYPE_V21_JAPANESE) || 250 (vcardType == VCARD_TYPE_V21_JAPANESE_UTF8) || 251 (vcardType == VCARD_TYPE_V30_JAPANESE) || 252 (vcardType == VCARD_TYPE_V30_JAPANESE_UTF8) || 253 (vcardType == VCARD_TYPE_DOCOMO)); 254 } 255 usesUtf8(int vcardType)256 public static boolean usesUtf8(int vcardType) { 257 return ((vcardType & FLAG_CHARSET_UTF8) != 0); 258 } 259 usesShiftJis(int vcardType)260 public static boolean usesShiftJis(int vcardType) { 261 return ((vcardType & FLAG_CHARSET_SHIFT_JIS) != 0); 262 } 263 264 /** 265 * @return true when Japanese phonetic string must be converted to a string 266 * containing only half-width katakana. This method exists since Japanese mobile 267 * phones usually use only half-width katakana for expressing phonetic names and 268 * some devices are not ready for parsing other phonetic strings like hiragana and 269 * full-width katakana. 270 */ needsToConvertPhoneticString(int vcardType)271 public static boolean needsToConvertPhoneticString(int vcardType) { 272 return (vcardType == VCARD_TYPE_DOCOMO); 273 } 274 getNameOrderType(int vcardType)275 public static int getNameOrderType(int vcardType) { 276 return vcardType & NAME_ORDER_MASK; 277 } 278 usesAndroidSpecificProperty(int vcardType)279 public static boolean usesAndroidSpecificProperty(int vcardType) { 280 return ((vcardType & FLAG_USE_ANDROID_PROPERTY) != 0); 281 } 282 usesDefactProperty(int vcardType)283 public static boolean usesDefactProperty(int vcardType) { 284 return ((vcardType & FLAG_USE_DEFACT_PROPERTY) != 0); 285 } 286 onlyOneNoteFieldIsAvailable(int vcardType)287 public static boolean onlyOneNoteFieldIsAvailable(int vcardType) { 288 return vcardType == VCARD_TYPE_DOCOMO; 289 } 290 showPerformanceLog()291 public static boolean showPerformanceLog() { 292 return (VCardConfig.LOG_LEVEL & VCardConfig.LOG_LEVEL_PERFORMANCE_MEASUREMENT) != 0; 293 } 294 295 /** 296 * @hide 297 */ usesQPToPrimaryProperties(int vcardType)298 public static boolean usesQPToPrimaryProperties(int vcardType) { 299 return (usesQuotedPrintable(vcardType) && 300 ((vcardType & FLAG_USE_QP_TO_PRIMARY_PROPERTIES) != 0)); 301 } 302 VCardConfig()303 private VCardConfig() { 304 } 305 }