VCardEntry.java revision 37634a0179f74431317f50d2ce493e3fad36f5a9
14199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa/*
24199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Copyright (C) 2009 The Android Open Source Project
34199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa *
44199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Licensed under the Apache License, Version 2.0 (the "License");
54199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * you may not use this file except in compliance with the License.
64199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * You may obtain a copy of the License at
74199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa *
84199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa *      http://www.apache.org/licenses/LICENSE-2.0
94199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa *
104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Unless required by applicable law or agreed to in writing, software
114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * distributed under the License is distributed on an "AS IS" BASIS,
124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * See the License for the specific language governing permissions and
144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * limitations under the License.
154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa */
164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawapackage com.android.vcard;
174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.accounts.Account;
194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.content.ContentProviderOperation;
204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.content.ContentProviderResult;
214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.content.ContentResolver;
224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.content.OperationApplicationException;
234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.net.Uri;
244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.os.RemoteException;
254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract;
264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Email;
274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Event;
284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.GroupMembership;
294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Im;
304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Nickname;
314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Note;
324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Organization;
334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Phone;
344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Photo;
3588d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.SipAddress;
364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.StructuredName;
374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.StructuredPostal;
384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.provider.ContactsContract.CommonDataKinds.Website;
3988d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawaimport android.provider.ContactsContract.Contacts;
4088d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawaimport android.provider.ContactsContract.Data;
4188d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawaimport android.provider.ContactsContract.RawContacts;
424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.telephony.PhoneNumberUtils;
434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.text.TextUtils;
444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.util.Log;
454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.ArrayList;
474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Arrays;
484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Collection;
494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Collections;
504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.HashMap;
514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.HashSet;
5237634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawaimport java.util.LinkedHashSet;
534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.List;
544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Map;
5537634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawaimport java.util.Set;
564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa/**
584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * This class bridges between data structure of Contact app and VCard data.
594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa */
604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawapublic class VCardEntry {
614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private static final String LOG_TAG = "VCardEntry";
624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private final static int DEFAULT_ORGANIZATION_TYPE = Organization.TYPE_WORK;
644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private static final Map<String, Integer> sImMap = new HashMap<String, Integer>();
664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    static {
684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_AIM, Im.PROTOCOL_AIM);
694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_MSN, Im.PROTOCOL_MSN);
704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_YAHOO, Im.PROTOCOL_YAHOO);
714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_ICQ, Im.PROTOCOL_ICQ);
724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_JABBER, Im.PROTOCOL_JABBER);
734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_SKYPE_USERNAME, Im.PROTOCOL_SKYPE);
744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.PROPERTY_X_GOOGLE_TALK, Im.PROTOCOL_GOOGLE_TALK);
754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        sImMap.put(VCardConstants.ImportOnly.PROPERTY_X_GOOGLE_TALK_WITH_SPACE,
764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                Im.PROTOCOL_GOOGLE_TALK);
774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static class PhoneData {
804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int type;
814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String data;
824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String label;
834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // isPrimary is (not final but) changable, only when there's no appropriate one existing
844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // in the original VCard.
854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean isPrimary;
864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public PhoneData(int type, String data, String label, boolean isPrimary) {
874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.type = type;
884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.data = data;
894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.label = label;
904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.isPrimary = isPrimary;
914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean equals(Object obj) {
954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(obj instanceof PhoneData)) {
964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            PhoneData phoneData = (PhoneData)obj;
994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (type == phoneData.type && data.equals(phoneData.data) &&
1004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    label.equals(phoneData.label) && isPrimary == phoneData.isPrimary);
1014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
1044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String toString() {
1054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return String.format("type: %d, data: %s, label: %s, isPrimary: %s",
1064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    type, data, label, isPrimary);
1074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
1094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static class EmailData {
1114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int type;
1124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String data;
1134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // Used only when TYPE is TYPE_CUSTOM.
1144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String label;
1154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean isPrimary;
1164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public EmailData(int type, String data, String label, boolean isPrimary) {
1174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.type = type;
1184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.data = data;
1194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.label = label;
1204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.isPrimary = isPrimary;
1214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
1244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean equals(Object obj) {
1254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(obj instanceof EmailData)) {
1264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
1274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            EmailData emailData = (EmailData)obj;
1294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (type == emailData.type && data.equals(emailData.data) &&
1304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    label.equals(emailData.label) && isPrimary == emailData.isPrimary);
1314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
1344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String toString() {
1354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return String.format("type: %d, data: %s, label: %s, isPrimary: %s",
1364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    type, data, label, isPrimary);
1374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
1394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static class PostalData {
1414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // Determined by vCard specification.
1424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // - PO Box, Extended Addr, Street, Locality, Region, Postal Code, Country Name
1434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public static final int ADDR_MAX_DATA_SIZE = 7;
1444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        private final String[] dataArray;
1454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String pobox;
1464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String extendedAddress;
1474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String street;
1484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String localty;
1494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String region;
1504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String postalCode;
1514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String country;
1524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int type;
1534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String label;
1544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean isPrimary;
1554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public PostalData(final int type, final List<String> propValueList,
1574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final String label, boolean isPrimary) {
1584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.type = type;
1594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            dataArray = new String[ADDR_MAX_DATA_SIZE];
1604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int size = propValueList.size();
1624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (size > ADDR_MAX_DATA_SIZE) {
1634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                size = ADDR_MAX_DATA_SIZE;
1644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // adr-value = 0*6(text-value ";") text-value
1674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            //           ; PO Box, Extended Address, Street, Locality, Region, Postal
1684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            //           ; Code, Country Name
1694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            //
1704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Use Iterator assuming List may be LinkedList, though actually it is
1714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // always ArrayList in the current implementation.
1724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int i = 0;
1734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String addressElement : propValueList) {
1744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                dataArray[i] = addressElement;
1754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (++i >= size) {
1764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    break;
1774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
1784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            while (i < ADDR_MAX_DATA_SIZE) {
1804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                dataArray[i++] = null;
1814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.pobox = dataArray[0];
1844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.extendedAddress = dataArray[1];
1854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.street = dataArray[2];
1864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.localty = dataArray[3];
1874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.region = dataArray[4];
1884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.postalCode = dataArray[5];
1894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.country = dataArray[6];
1904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.label = label;
1914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.isPrimary = isPrimary;
1924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
1934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
1954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean equals(Object obj) {
1964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(obj instanceof PostalData)) {
1974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
1984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
1994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final PostalData postalData = (PostalData)obj;
2004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (Arrays.equals(dataArray, postalData.dataArray) &&
2014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    (type == postalData.type &&
2024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            (type == StructuredPostal.TYPE_CUSTOM ?
2034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                                    (label == postalData.label) : true)) &&
2044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    (isPrimary == postalData.isPrimary));
2054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String getFormattedAddress(final int vcardType) {
2084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            StringBuilder builder = new StringBuilder();
2094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean empty = true;
2104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (VCardConfig.isJapaneseDevice(vcardType)) {
2114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // In Japan, the order is reversed.
2124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (int i = ADDR_MAX_DATA_SIZE - 1; i >= 0; i--) {
2134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    String addressPart = dataArray[i];
2144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (!TextUtils.isEmpty(addressPart)) {
2154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        if (!empty) {
2164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            builder.append(' ');
2174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        } else {
2184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            empty = false;
2194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
2204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        builder.append(addressPart);
2214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
2224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
2234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
2244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (int i = 0; i < ADDR_MAX_DATA_SIZE; i++) {
2254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    String addressPart = dataArray[i];
2264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (!TextUtils.isEmpty(addressPart)) {
2274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        if (!empty) {
2284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            builder.append(' ');
2294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        } else {
2304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            empty = false;
2314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
2324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        builder.append(addressPart);
2334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
2344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
2354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
2364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return builder.toString().trim();
2384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
2414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String toString() {
2424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return String.format("type: %d, label: %s, isPrimary: %s",
2434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    type, label, isPrimary);
2444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
2464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static class OrganizationData {
2484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int type;
2494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // non-final is Intentional: we may change the values since this info is separated into
2504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // two parts in vCard: "ORG" + "TITLE", and we have to cope with each field in
2514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // different timing.
2524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String companyName;
2534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String departmentName;
2544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String titleName;
2554560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        public final String phoneticName;  // We won't have this in "TITLE" property.
2564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean isPrimary;
2574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public OrganizationData(int type,
2594560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                final String companyName,
2604560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                final String departmentName,
2614560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                final String titleName,
2624560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                final String phoneticName,
2634560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                final boolean isPrimary) {
2644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.type = type;
2654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.companyName = companyName;
2664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.departmentName = departmentName;
2674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.titleName = titleName;
2684560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            this.phoneticName = phoneticName;
2694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.isPrimary = isPrimary;
2704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
2734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean equals(Object obj) {
2744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(obj instanceof OrganizationData)) {
2754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
2764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
2774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            OrganizationData organization = (OrganizationData)obj;
2784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (type == organization.type &&
2794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    TextUtils.equals(companyName, organization.companyName) &&
2804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    TextUtils.equals(departmentName, organization.departmentName) &&
2814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    TextUtils.equals(titleName, organization.titleName) &&
2824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    isPrimary == organization.isPrimary);
2834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
2844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String getFormattedString() {
2864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final StringBuilder builder = new StringBuilder();
2874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!TextUtils.isEmpty(companyName)) {
2884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.append(companyName);
2894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
2904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!TextUtils.isEmpty(departmentName)) {
2924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (builder.length() > 0) {
2934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.append(", ");
2944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
2954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.append(departmentName);
2964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
2974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
2984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!TextUtils.isEmpty(titleName)) {
2994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (builder.length() > 0) {
3004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.append(", ");
3014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
3024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.append(titleName);
3034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
3044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return builder.toString();
3064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
3094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String toString() {
3104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return String.format(
3114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    "type: %d, company: %s, department: %s, title: %s, isPrimary: %s",
3124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    type, companyName, departmentName, titleName, isPrimary);
3134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
3154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static class ImData {
3174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int protocol;
3184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String customProtocol;
3194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int type;
3204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String data;
3214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final boolean isPrimary;
3224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public ImData(final int protocol, final String customProtocol, final int type,
3244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final String data, final boolean isPrimary) {
3254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.protocol = protocol;
3264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.customProtocol = customProtocol;
3274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.type = type;
3284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.data = data;
3294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.isPrimary = isPrimary;
3304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
3334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean equals(Object obj) {
3344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(obj instanceof ImData)) {
3354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
3364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
3374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            ImData imData = (ImData)obj;
3384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (type == imData.type && protocol == imData.protocol
3394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    && (customProtocol != null ? customProtocol.equals(imData.customProtocol) :
3404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        (imData.customProtocol == null))
3414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    && (data != null ? data.equals(imData.data) : (imData.data == null))
3424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    && isPrimary == imData.isPrimary);
3434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
3464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String toString() {
3474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return String.format(
3484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    "type: %d, protocol: %d, custom_protcol: %s, data: %s, isPrimary: %s",
3494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    type, protocol, customProtocol, data, isPrimary);
3504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
3524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static class PhotoData {
3544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public static final String FORMAT_FLASH = "SWF";
3554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final int type;
3564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final String formatName;  // used when type is not defined in ContactsContract.
3574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final byte[] photoBytes;
3584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final boolean isPrimary;
3594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public PhotoData(int type, String formatName, byte[] photoBytes, boolean isPrimary) {
3614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.type = type;
3624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.formatName = formatName;
3634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.photoBytes = photoBytes;
3644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            this.isPrimary = isPrimary;
3654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
3684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public boolean equals(Object obj) {
3694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(obj instanceof PhotoData)) {
3704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return false;
3714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
3724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            PhotoData photoData = (PhotoData)obj;
3734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (type == photoData.type &&
3744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    (formatName == null ? (photoData.formatName == null) :
3754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            formatName.equals(photoData.formatName)) &&
3764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    (Arrays.equals(photoBytes, photoData.photoBytes)) &&
3774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    (isPrimary == photoData.isPrimary));
3784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        @Override
3814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public String toString() {
3824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return String.format("type: %d, format: %s: size: %d, isPrimary: %s",
3834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    type, formatName, photoBytes.length, isPrimary);
3844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
3864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /* package */ static class Property {
3884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        private String mPropertyName;
3894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        private Map<String, Collection<String>> mParameterMap =
3904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            new HashMap<String, Collection<String>>();
3914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        private List<String> mPropertyValueList = new ArrayList<String>();
3924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        private byte[] mPropertyBytes;
3934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public void setPropertyName(final String propertyName) {
3954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPropertyName = propertyName;
3964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
3974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
3984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public void addParameter(final String paramName, final String paramValue) {
3994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collection<String> values;
4004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!mParameterMap.containsKey(paramName)) {
4014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (paramName.equals("TYPE")) {
4024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    values = new HashSet<String>();
4034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                } else {
4044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    values = new ArrayList<String>();
4054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
4064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                mParameterMap.put(paramName, values);
4074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
4084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                values = mParameterMap.get(paramName);
4094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
4104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            values.add(paramValue);
4114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
4124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public void addToPropertyValueList(final String propertyValue) {
4144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPropertyValueList.add(propertyValue);
4154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
4164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public void setPropertyBytes(final byte[] propertyBytes) {
4184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPropertyBytes = propertyBytes;
4194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
4204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final Collection<String> getParameters(String type) {
4224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return mParameterMap.get(type);
4234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
4244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public final List<String> getPropertyValueList() {
4264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return mPropertyValueList;
4274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
4284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        public void clear() {
4304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPropertyName = null;
4314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mParameterMap.clear();
4324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPropertyValueList.clear();
4334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPropertyBytes = null;
4344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
4354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
4364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4374560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    // TODO(dmiyakawa): vCard 4.0 logically has multiple formatted names and we need to
4384560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    // select the most preferable one using PREF parameter.
4394560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    //
4404560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    // e.g. (based on rev.13)
4414560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    // FN;PREF=1:John M. Doe
4424560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    // FN;PREF=2:John Doe
4434560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    // FN;PREF=3;John
4444560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa
4454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mFamilyName;
4464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mGivenName;
4474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mMiddleName;
4484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mPrefix;
4494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mSuffix;
4504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // Used only when no family nor given name is found.
4524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mFormattedName;
4534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mPhoneticFamilyName;
4554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mPhoneticGivenName;
4564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mPhoneticMiddleName;
4574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mPhoneticFullName;
4594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<String> mNickNameList;
4614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mDisplayName;
4634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String mBirthday;
465c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa    private String mAnniversary;
4664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<String> mNoteList;
4684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<PhoneData> mPhoneList;
4694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<EmailData> mEmailList;
4704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<PostalData> mPostalList;
4714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<OrganizationData> mOrganizationList;
4724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<ImData> mImList;
4734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<PhotoData> mPhotoList;
4744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<String> mWebsiteList;
47537634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa    private Set<String> mSipSet;
4764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private List<List<String>> mAndroidCustomPropertyList;
4774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private final int mVCardType;
4794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private final Account mAccount;
4804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public VCardEntry() {
4824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        this(VCardConfig.VCARD_TYPE_V21_GENERIC);
4834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
4844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public VCardEntry(int vcardType) {
4864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        this(vcardType, null);
4874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
4884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public VCardEntry(int vcardType, Account account) {
4904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mVCardType = vcardType;
4914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mAccount = account;
4924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
4934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
4944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addPhone(int type, String data, String label, boolean isPrimary) {
4954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPhoneList == null) {
4964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhoneList = new ArrayList<PhoneData>();
4974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
4984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final StringBuilder builder = new StringBuilder();
4994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final String trimed = data.trim();
5004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final String formattedNumber;
5014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (type == Phone.TYPE_PAGER || VCardConfig.refrainPhoneNumberFormatting(mVCardType)) {
5024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            formattedNumber = trimed;
5034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else {
5044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final int length = trimed.length();
5054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (int i = 0; i < length; i++) {
5064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                char ch = trimed.charAt(i);
5074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (('0' <= ch && ch <= '9') || (i == 0 && ch == '+')) {
5084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.append(ch);
5094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
5104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
5114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final int formattingType = VCardUtils.getPhoneNumberFormat(mVCardType);
5134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            formattedNumber = PhoneNumberUtils.formatNumber(builder.toString(), formattingType);
5144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
5154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        PhoneData phoneData = new PhoneData(type, formattedNumber, label, isPrimary);
5164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mPhoneList.add(phoneData);
5174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
5184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addNickName(final String nickName) {
5204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mNickNameList == null) {
5214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mNickNameList = new ArrayList<String>();
5224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
5234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mNickNameList.add(nickName);
5244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
5254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addEmail(int type, String data, String label, boolean isPrimary){
5274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mEmailList == null) {
5284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mEmailList = new ArrayList<EmailData>();
5294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
5304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mEmailList.add(new EmailData(type, data, label, isPrimary));
5314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
5324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addPostal(int type, List<String> propValueList, String label, boolean isPrimary){
5344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPostalList == null) {
5354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPostalList = new ArrayList<PostalData>(0);
5364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
5374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mPostalList.add(new PostalData(type, propValueList, label, isPrimary));
5384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
5394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
5414560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * Should be called via {@link #handleOrgValue(int, List, Map, boolean) or
5424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * {@link #handleTitleValue(String)}.
5434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
5444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addNewOrganization(int type, final String companyName,
5454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final String departmentName,
5464560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            final String titleName,
5474560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            final String phoneticName,
5484560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            final boolean isPrimary) {
5494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mOrganizationList == null) {
5504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mOrganizationList = new ArrayList<OrganizationData>();
5514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
5524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mOrganizationList.add(new OrganizationData(type, companyName,
5534560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                departmentName, titleName, phoneticName, isPrimary));
5544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
5554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private static final List<String> sEmptyList =
5574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collections.unmodifiableList(new ArrayList<String>(0));
5584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
5594560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    private String buildSinglePhoneticNameFromSortAsParam(Map<String, Collection<String>> paramMap) {
5604560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        final Collection<String> sortAsCollection = paramMap.get(VCardConstants.PARAM_SORT_AS);
5614560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        if (sortAsCollection != null && sortAsCollection.size() != 0) {
5624560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            if (sortAsCollection.size() > 1) {
5634560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                Log.w(LOG_TAG, "Incorrect multiple SORT_AS parameters detected: " +
5644560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                        Arrays.toString(sortAsCollection.toArray()));
5654560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            }
5664560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            final List<String> sortNames =
5674560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                    VCardUtils.constructListFromValue(sortAsCollection.iterator().next(),
5684560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                            mVCardType);
5694560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            final StringBuilder builder = new StringBuilder();
5704560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            for (final String elem : sortNames) {
5714560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                builder.append(elem);
5724560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            }
5734560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            return builder.toString();
5744560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        } else {
5754560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            return null;
5764560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        }
5774560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    }
5784560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa
5794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
5804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * Set "ORG" related values to the appropriate data. If there's more than one
5814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * {@link OrganizationData} objects, this input data are attached to the last one which
5824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * does not have valid values (not including empty but only null). If there's no
5834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * {@link OrganizationData} object, a new {@link OrganizationData} is created,
5844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * whose title is set to null.
5854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
5864560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    private void handleOrgValue(final int type, List<String> orgList,
5874560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            Map<String, Collection<String>> paramMap, boolean isPrimary) {
5884560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        final String phoneticName = buildSinglePhoneticNameFromSortAsParam(paramMap);
5894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (orgList == null) {
5904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            orgList = sEmptyList;
5914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
5924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final String companyName;
5934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final String departmentName;
5944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final int size = orgList.size();
5954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        switch (size) {
5964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            case 0: {
5974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                companyName = "";
5984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                departmentName = null;
5994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                break;
6004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
6014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            case 1: {
6024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                companyName = orgList.get(0);
6034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                departmentName = null;
6044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                break;
6054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
6064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            default: {  // More than 1.
6074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                companyName = orgList.get(0);
6084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // We're not sure which is the correct string for department.
6094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // In order to keep all the data, concatinate the rest of elements.
6104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                StringBuilder builder = new StringBuilder();
6114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (int i = 1; i < size; i++) {
6124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (i > 1) {
6134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        builder.append(' ');
6144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
6154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.append(orgList.get(i));
6164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
6174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                departmentName = builder.toString();
6184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
6194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mOrganizationList == null) {
6214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Create new first organization entry, with "null" title which may be
6224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // added via handleTitleValue().
6234560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            addNewOrganization(type, companyName, departmentName, null, phoneticName, isPrimary);
6244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return;
6254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        for (OrganizationData organizationData : mOrganizationList) {
6274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Not use TextUtils.isEmpty() since ORG was set but the elements might be empty.
6284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // e.g. "ORG;PREF:;" -> Both companyName and departmentName become empty but not null.
6294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (organizationData.companyName == null &&
6304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    organizationData.departmentName == null) {
6314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // Probably the "TITLE" property comes before the "ORG" property via
6324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // handleTitleLine().
6334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                organizationData.companyName = companyName;
6344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                organizationData.departmentName = departmentName;
6354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                organizationData.isPrimary = isPrimary;
6364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return;
6374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
6384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // No OrganizatioData is available. Create another one, with "null" title, which may be
6404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // added via handleTitleValue().
6414560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        addNewOrganization(type, companyName, departmentName, null, phoneticName, isPrimary);
6424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
6434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
6444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
6454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * Set "title" value to the appropriate data. If there's more than one
6464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * OrganizationData objects, this input is attached to the last one which does not
6474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * have valid title value (not including empty but only null). If there's no
6484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * OrganizationData object, a new OrganizationData is created, whose company name is
6494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * set to null.
6504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
6514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void handleTitleValue(final String title) {
6524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mOrganizationList == null) {
6534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Create new first organization entry, with "null" other info, which may be
6544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // added via handleOrgValue().
6554560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            addNewOrganization(DEFAULT_ORGANIZATION_TYPE, null, null, title, null, false);
6564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return;
6574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        for (OrganizationData organizationData : mOrganizationList) {
6594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (organizationData.titleName == null) {
6604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                organizationData.titleName = title;
6614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return;
6624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
6634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // No Organization is available. Create another one, with "null" other info, which may be
6654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // added via handleOrgValue().
6664560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        addNewOrganization(DEFAULT_ORGANIZATION_TYPE, null, null, title, null, false);
6674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
6684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
6694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addIm(int protocol, String customProtocol, int type,
6704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            String propValue, boolean isPrimary) {
6714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mImList == null) {
6724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mImList = new ArrayList<ImData>();
6734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mImList.add(new ImData(protocol, customProtocol, type, propValue, isPrimary));
6754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
6764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
6774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addNote(final String note) {
6784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mNoteList == null) {
6794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mNoteList = new ArrayList<String>(1);
6804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mNoteList.add(note);
6824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
6834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
6844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void addPhotoBytes(String formatName, byte[] photoBytes, boolean isPrimary) {
6854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPhotoList == null) {
6864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhotoList = new ArrayList<PhotoData>(1);
6874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
6884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final PhotoData photoData = new PhotoData(0, null, photoBytes, isPrimary);
6894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mPhotoList.add(photoData);
6904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
6914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
6924560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    /**
6934560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * Tries to extract paramMap, constructs SORT-AS parameter values, and store them in
6944560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * appropriate phonetic name variables.
6954560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     *
6964560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * This method does not care the vCard version. Even when we have SORT-AS parameters in
6974560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * invalid versions (i.e. 2.1 and 3.0), we scilently accept them so that we won't drop
6984560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * meaningful information. If we had this parameter in the N field of vCard 3.0, and
6994560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * the contact data also have SORT-STRING, we will prefer SORT-STRING, since it is
7004560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     * regitimate property to be understood.
7014560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa     */
7024560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    private void tryHandleSortAsName(final Map<String, Collection<String>> paramMap) {
7034560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        if (VCardConfig.isVersion30(mVCardType) &&
7044560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                !(TextUtils.isEmpty(mPhoneticFamilyName) &&
7054560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                        TextUtils.isEmpty(mPhoneticMiddleName) &&
7064560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                        TextUtils.isEmpty(mPhoneticGivenName))) {
7074560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            return;
7084560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        }
7094560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa
7104560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        final Collection<String> sortAsCollection = paramMap.get(VCardConstants.PARAM_SORT_AS);
7114560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        if (sortAsCollection != null && sortAsCollection.size() != 0) {
7124560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            if (sortAsCollection.size() > 1) {
7134560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                Log.w(LOG_TAG, "Incorrect multiple SORT_AS parameters detected: " +
7144560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                        Arrays.toString(sortAsCollection.toArray()));
7154560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            }
7164560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            final List<String> sortNames =
7174560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                    VCardUtils.constructListFromValue(sortAsCollection.iterator().next(),
7184560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                            mVCardType);
7194560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            int size = sortNames.size();
7204560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            if (size > 3) {
7214560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                size = 3;
7224560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            }
7234560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            switch (size) {
7244560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            case 3: mPhoneticMiddleName = sortNames.get(2); //$FALL-THROUGH$
7254560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            case 2: mPhoneticGivenName = sortNames.get(1); //$FALL-THROUGH$
7264560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            default: mPhoneticFamilyName = sortNames.get(0); break;
7274560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            }
7284560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        }
7294560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    }
7304560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa
7314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    @SuppressWarnings("fallthrough")
7324560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa    private void handleNProperty(final List<String> paramValues,
7334560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            Map<String, Collection<String>> paramMap) {
7344560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        // in vCard 4.0, SORT-AS parameter is available.
7354560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        tryHandleSortAsName(paramMap);
7364560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa
7374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // Family, Given, Middle, Prefix, Suffix. (1 - 5)
7384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        int size;
7394560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        if (paramValues == null || (size = paramValues.size()) < 1) {
7404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return;
7414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
7424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (size > 5) {
7434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            size = 5;
7444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
7454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
7464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        switch (size) {
7474560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        // Fall-through.
7484560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        case 5: mSuffix = paramValues.get(4);
7494560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        case 4: mPrefix = paramValues.get(3);
7504560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        case 3: mMiddleName = paramValues.get(2);
7514560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        case 2: mGivenName = paramValues.get(1);
7524560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa        default: mFamilyName = paramValues.get(0);
7534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
7544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
7554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
7564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
7574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * Note: Some Japanese mobile phones use this field for phonetic name,
7584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     *       since vCard 2.1 does not have "SORT-STRING" type.
7594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     *       Also, in some cases, the field has some ';'s in it.
7604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     *       Assume the ';' means the same meaning in N property
7614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
7624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    @SuppressWarnings("fallthrough")
7634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void handlePhoneticNameFromSound(List<String> elems) {
7644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (!(TextUtils.isEmpty(mPhoneticFamilyName) &&
7654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                TextUtils.isEmpty(mPhoneticMiddleName) &&
7664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                TextUtils.isEmpty(mPhoneticGivenName))) {
7674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // This means the other properties like "X-PHONETIC-FIRST-NAME" was already found.
7684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Ignore "SOUND;X-IRMC-N".
7694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return;
7704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
7714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
7724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        int size;
7734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (elems == null || (size = elems.size()) < 1) {
7744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return;
7754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
7764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
7774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // Assume that the order is "Family, Given, Middle".
7784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // This is not from specification but mere assumption. Some Japanese phones use this order.
7794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (size > 3) {
7804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            size = 3;
7814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
7824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
7834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (elems.get(0).length() > 0) {
7844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean onlyFirstElemIsNonEmpty = true;
7854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (int i = 1; i < size; i++) {
7864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (elems.get(i).length() > 0) {
7874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    onlyFirstElemIsNonEmpty = false;
7884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    break;
7894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
7904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
7914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (onlyFirstElemIsNonEmpty) {
7924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final String[] namesArray = elems.get(0).split(" ");
7934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final int nameArrayLength = namesArray.length;
7944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (nameArrayLength == 3) {
7954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    // Assume the string is "Family Middle Given".
7964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticFamilyName = namesArray[0];
7974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticMiddleName = namesArray[1];
7984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticGivenName = namesArray[2];
7994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                } else if (nameArrayLength == 2) {
8004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    // Assume the string is "Family Given" based on the Japanese mobile
8014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    // phones' preference.
8024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticFamilyName = namesArray[0];
8034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticGivenName = namesArray[1];
8044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                } else {
8054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticFullName = elems.get(0);
8064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
8074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return;
8084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
8094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
8104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        switch (size) {
8124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // fallthrough
8134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            case 3: mPhoneticMiddleName = elems.get(2);
8144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            case 2: mPhoneticGivenName = elems.get(1);
8154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            default: mPhoneticFamilyName = elems.get(0);
8164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
8174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
8184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public void addProperty(final Property property) {
8204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final String propName = property.mPropertyName;
8214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final Map<String, Collection<String>> paramMap = property.mParameterMap;
8224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final List<String> propValueList = property.mPropertyValueList;
8234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        byte[] propBytes = property.mPropertyBytes;
8244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (propValueList.size() == 0) {
8264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return;
8274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
8284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final String propValue = listToString(propValueList).trim();
8294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (propName.equals(VCardConstants.PROPERTY_VERSION)) {
8314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // vCard version. Ignore this.
8324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_FN)) {
8334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mFormattedName = propValue;
8344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_NAME) && mFormattedName == null) {
8354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // Only in vCard 3.0. Use this if FN, which must exist in vCard 3.0 but may not
8364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // actually exist in the real vCard data, does not exist.
8374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mFormattedName = propValue;
8384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_N)) {
8394560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            handleNProperty(propValueList, paramMap);
8404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_SORT_STRING)) {
8414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhoneticFullName = propValue;
8424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_NICKNAME) ||
8434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                propName.equals(VCardConstants.ImportOnly.PROPERTY_X_NICKNAME)) {
8444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            addNickName(propValue);
8454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_SOUND)) {
8464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
8474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeCollection != null
8484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    && typeCollection.contains(VCardConstants.PARAM_TYPE_X_IRMC_N)) {
8494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // As of 2009-10-08, Parser side does not split a property value into separated
8504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // values using ';' (in other words, propValueList.size() == 1),
8514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // which is correct behavior from the view of vCard 2.1.
8524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // But we want it to be separated, so do the separation here.
8534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final List<String> phoneticNameList =
8544560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                        VCardUtils.constructListFromValue(propValue, mVCardType);
8554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                handlePhoneticNameFromSound(phoneticNameList);
8564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
8574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // Ignore this field since Android cannot understand what it is.
8584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
8594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_ADR)) {
8604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean valuesAreAllEmpty = true;
8614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String value : propValueList) {
8624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (value.length() > 0) {
8634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    valuesAreAllEmpty = false;
8644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    break;
8654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
8664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
8674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (valuesAreAllEmpty) {
8684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                return;
8694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
8704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
8714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int type = -1;
8724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            String label = "";
8734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean isPrimary = false;
8744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
8754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeCollection != null) {
8764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (String typeString : typeCollection) {
8774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    typeString = typeString.toUpperCase();
8784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (typeString.equals(VCardConstants.PARAM_TYPE_PREF)) {
8794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        isPrimary = true;
8804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else if (typeString.equals(VCardConstants.PARAM_TYPE_HOME)) {
8814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = StructuredPostal.TYPE_HOME;
8824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        label = "";
8834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else if (typeString.equals(VCardConstants.PARAM_TYPE_WORK) ||
8844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            typeString.equalsIgnoreCase(VCardConstants.PARAM_EXTRA_TYPE_COMPANY)) {
8854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // "COMPANY" seems emitted by Windows Mobile, which is not
8864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // specifically supported by vCard 2.1. We assume this is same
8874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // as "WORK".
8884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = StructuredPostal.TYPE_WORK;
8894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        label = "";
8904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else if (typeString.equals(VCardConstants.PARAM_ADR_TYPE_PARCEL) ||
8914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            typeString.equals(VCardConstants.PARAM_ADR_TYPE_DOM) ||
8924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            typeString.equals(VCardConstants.PARAM_ADR_TYPE_INTL)) {
8934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // We do not have any appropriate way to store this information.
8944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else {
8954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        if (typeString.startsWith("X-") && type < 0) {
8964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            typeString = typeString.substring(2);
8974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
8984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // vCard 3.0 allows iana-token. Also some vCard 2.1 exporters
8994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // emit non-standard types. We do not handle their values now.
9004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = StructuredPostal.TYPE_CUSTOM;
9014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        label = typeString;
9024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
9034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
9044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // We use "HOME" as default
9064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (type < 0) {
9074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                type = StructuredPostal.TYPE_HOME;
9084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
9104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            addPostal(type, propValueList, label, isPrimary);
9114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_EMAIL)) {
9124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int type = -1;
9134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            String label = null;
9144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean isPrimary = false;
9154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
9164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeCollection != null) {
9174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (String typeString : typeCollection) {
9184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    typeString = typeString.toUpperCase();
9194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (typeString.equals(VCardConstants.PARAM_TYPE_PREF)) {
9204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        isPrimary = true;
9214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else if (typeString.equals(VCardConstants.PARAM_TYPE_HOME)) {
9224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = Email.TYPE_HOME;
9234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else if (typeString.equals(VCardConstants.PARAM_TYPE_WORK)) {
9244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = Email.TYPE_WORK;
9254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else if (typeString.equals(VCardConstants.PARAM_TYPE_CELL)) {
9264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = Email.TYPE_MOBILE;
9274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else {
9284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        if (typeString.startsWith("X-") && type < 0) {
9294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            typeString = typeString.substring(2);
9304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
9314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // vCard 3.0 allows iana-token.
9324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // We may have INTERNET (specified in vCard spec),
9334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        // SCHOOL, etc.
9344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        type = Email.TYPE_CUSTOM;
9354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        label = typeString;
9364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
9374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
9384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (type < 0) {
9404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                type = Email.TYPE_OTHER;
9414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            addEmail(type, propValue, label, isPrimary);
9434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_ORG)) {
9444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // vCard specification does not specify other types.
9454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final int type = Organization.TYPE_WORK;
9464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean isPrimary = false;
9474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
9484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeCollection != null) {
9494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (String typeString : typeCollection) {
9504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (typeString.equals(VCardConstants.PARAM_TYPE_PREF)) {
9514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        isPrimary = true;
9524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
9534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
9544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9554560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa            handleOrgValue(type, propValueList, paramMap, isPrimary);
9564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_TITLE)) {
9574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            handleTitleValue(propValue);
9584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_ROLE)) {
9594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // This conflicts with TITLE. Ignore for now...
9604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // handleTitleValue(propValue);
9614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_PHOTO) ||
9624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                propName.equals(VCardConstants.PROPERTY_LOGO)) {
9634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collection<String> paramMapValue = paramMap.get("VALUE");
9644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (paramMapValue != null && paramMapValue.contains("URL")) {
9654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // Currently we do not have appropriate example for testing this case.
9664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
9674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                final Collection<String> typeCollection = paramMap.get("TYPE");
9684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                String formatName = null;
9694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                boolean isPrimary = false;
9704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (typeCollection != null) {
9714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    for (String typeValue : typeCollection) {
9724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        if (VCardConstants.PARAM_TYPE_PREF.equals(typeValue)) {
9734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            isPrimary = true;
9744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        } else if (formatName == null){
9754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            formatName = typeValue;
9764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
9774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
9784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
9794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                addPhotoBytes(formatName, propBytes, isPrimary);
9804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
9814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_TEL)) {
98237634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa            final String phoneNumber;
98337634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa            if (VCardConfig.isVersion40(mVCardType)) {
98437634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                // Given propValue is in URI format, not in phone number format used until
98537634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                // vCard 3.0.
98637634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                if (propValue.startsWith("sip:") ) {
98737634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    if (propValue.length() > 4) {
98837634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                        if (mSipSet == null) {
98937634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                            mSipSet = new LinkedHashSet<String>();
99037634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                        }
99137634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                        mSipSet.add(propValue.substring(4));
99237634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    }
99337634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    return;
99437634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                } else if (propValue.startsWith("tel:")) {
99537634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    phoneNumber = propValue.substring(4);
99637634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                } else {
99737634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    // We don't know appropriate way to handle the other schemas. Also,
99837634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    // we may still have non-URI phone number. To keep given data as much as
99937634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    // we can, just save original value here.
100037634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    phoneNumber = propValue;
100137634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                }
100237634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa            } else {
100337634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                phoneNumber = propValue;
100437634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa            }
100537634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa
100637634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa            if (propValue.length() == 0) {
100737634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                return;
100837634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa            }
10094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
10104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final Object typeObject =
101137634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    VCardUtils.getPhoneTypeFromStrings(typeCollection, phoneNumber);
10124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final int type;
10134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final String label;
10144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeObject instanceof Integer) {
10154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                type = (Integer)typeObject;
10164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                label = null;
10174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
10184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                type = Phone.TYPE_CUSTOM;
10194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                label = typeObject.toString();
10204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
10214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
10224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final boolean isPrimary;
102337634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa            if (typeCollection != null &&
102437634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    typeCollection.contains(VCardConstants.PARAM_TYPE_PREF)) {
10254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                isPrimary = true;
10264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
10274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                isPrimary = false;
10284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
102937634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa            addPhone(type, phoneNumber, label, isPrimary);
10304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_X_SKYPE_PSTNNUMBER)) {
10314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // The phone number available via Skype.
10324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
10334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final int type = Phone.TYPE_OTHER;
10344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final boolean isPrimary;
10354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeCollection != null && typeCollection.contains(VCardConstants.PARAM_TYPE_PREF)) {
10364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                isPrimary = true;
10374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else {
10384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                isPrimary = false;
10394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
10404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            addPhone(type, propValue, null, isPrimary);
10414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (sImMap.containsKey(propName)) {
10424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final int protocol = sImMap.get(propName);
10434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            boolean isPrimary = false;
10444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int type = -1;
10454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final Collection<String> typeCollection = paramMap.get(VCardConstants.PARAM_TYPE);
10464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (typeCollection != null) {
10474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (String typeString : typeCollection) {
10484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (typeString.equals(VCardConstants.PARAM_TYPE_PREF)) {
10494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        isPrimary = true;
10504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else if (type < 0) {
10514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        if (typeString.equalsIgnoreCase(VCardConstants.PARAM_TYPE_HOME)) {
10524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            type = Im.TYPE_HOME;
10534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        } else if (typeString.equalsIgnoreCase(VCardConstants.PARAM_TYPE_WORK)) {
10544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            type = Im.TYPE_WORK;
10554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
10564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
10574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
10584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
10594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (type < 0) {
106006ae82316d0b5f7222a7a1d15b7d03df88fdea15Daisuke Miyakawa                type = Im.TYPE_HOME;
10614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
10624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            addIm(protocol, null, type, propValue, isPrimary);
10634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_NOTE)) {
10644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            addNote(propValue);
10654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_URL)) {
10664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (mWebsiteList == null) {
10674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                mWebsiteList = new ArrayList<String>(1);
10684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
10694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mWebsiteList.add(propValue);
10704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_BDAY)) {
10714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mBirthday = propValue;
1072c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_ANNIVERSARY)) {
1073c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa            mAnniversary = propValue;
10744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_X_PHONETIC_FIRST_NAME)) {
10754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhoneticGivenName = propValue;
10764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_X_PHONETIC_MIDDLE_NAME)) {
10774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhoneticMiddleName = propValue;
10784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_X_PHONETIC_LAST_NAME)) {
10794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhoneticFamilyName = propValue;
108088d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_IMPP)) {
108188d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa            // See also RFC 4770 (for vCard 3.0)
108288d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa            if (propValue.startsWith("sip:") && propValue.length() > 4) {
108337634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                if (mSipSet == null) {
108437634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    mSipSet = new LinkedHashSet<String>();
108588d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa                }
108637634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                mSipSet.add(propValue.substring(4));
108788d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa            }
10885db8b7baeffb35191032789cb0b0d643b78f0120Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_X_SIP)) {
10895db8b7baeffb35191032789cb0b0d643b78f0120Daisuke Miyakawa            if (!TextUtils.isEmpty(propValue)) {
109037634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                if (mSipSet == null) {
109137634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    mSipSet = new LinkedHashSet<String>();
10925db8b7baeffb35191032789cb0b0d643b78f0120Daisuke Miyakawa                }
10930fc278de46840f89c01aa984de7565c1f97e3103Daisuke Miyakawa
109437634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                if (propValue.startsWith("sip:")) {
109537634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    if (propValue.length() > 4) {
109637634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                        mSipSet.add(propValue.substring(4));
109737634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    } else {
109837634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                        // Empty sip value. Ignore.
109937634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    }
11000fc278de46840f89c01aa984de7565c1f97e3103Daisuke Miyakawa                } else {
110137634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa                    mSipSet.add(propValue);
11020fc278de46840f89c01aa984de7565c1f97e3103Daisuke Miyakawa                }
11035db8b7baeffb35191032789cb0b0d643b78f0120Daisuke Miyakawa            }
11044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (propName.equals(VCardConstants.PROPERTY_X_ANDROID_CUSTOM)) {
11054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            final List<String> customPropertyList =
11064560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                VCardUtils.constructListFromValue(propValue, mVCardType);
11074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            handleAndroidCustomProperty(customPropertyList);
11084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else {
11094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
111037634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa        // Be careful when adding some logic here, as some blocks above may use "return".
11114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
11124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void handleAndroidCustomProperty(final List<String> customPropertyList) {
11144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mAndroidCustomPropertyList == null) {
11154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mAndroidCustomPropertyList = new ArrayList<List<String>>();
11164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
11174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        mAndroidCustomPropertyList.add(customPropertyList);
11184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
11194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
11214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * Construct the display name. The constructed data must not be null.
11224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
11234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private void constructDisplayName() {
11244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // FullName (created via "FN" or "NAME" field) is prefered.
11254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (!TextUtils.isEmpty(mFormattedName)) {
11264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = mFormattedName;
11274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (!(TextUtils.isEmpty(mFamilyName) && TextUtils.isEmpty(mGivenName))) {
11284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = VCardUtils.constructNameFromElements(mVCardType,
11294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mFamilyName, mMiddleName, mGivenName, mPrefix, mSuffix);
11304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (!(TextUtils.isEmpty(mPhoneticFamilyName) &&
11314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                TextUtils.isEmpty(mPhoneticGivenName))) {
11324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = VCardUtils.constructNameFromElements(mVCardType,
11334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    mPhoneticFamilyName, mPhoneticMiddleName, mPhoneticGivenName);
11344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (mEmailList != null && mEmailList.size() > 0) {
11354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = mEmailList.get(0).data;
11364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (mPhoneList != null && mPhoneList.size() > 0) {
11374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = mPhoneList.get(0).data;
11384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (mPostalList != null && mPostalList.size() > 0) {
11394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = mPostalList.get(0).getFormattedAddress(mVCardType);
11404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (mOrganizationList != null && mOrganizationList.size() > 0) {
11414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = mOrganizationList.get(0).getFormattedString();
11424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
11434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mDisplayName == null) {
11454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mDisplayName = "";
11464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
11474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
11484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    /**
11504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     * Consolidate several fielsds (like mName) using name candidates,
11514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa     */
11524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public void consolidateFields() {
11534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        constructDisplayName();
11544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPhoneticFullName != null) {
11564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            mPhoneticFullName = mPhoneticFullName.trim();
11574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
11584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
11594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public Uri pushIntoContentResolver(ContentResolver resolver) {
11614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        ArrayList<ContentProviderOperation> operationList =
11624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            new ArrayList<ContentProviderOperation>();
11634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // After applying the batch the first result's Uri is returned so it is important that
11644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        // the RawContact is the first operation that gets inserted into the list
11654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        ContentProviderOperation.Builder builder =
11664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            ContentProviderOperation.newInsert(RawContacts.CONTENT_URI);
11674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        String myGroupsId = null;
11684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mAccount != null) {
11694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(RawContacts.ACCOUNT_NAME, mAccount.name);
11704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(RawContacts.ACCOUNT_TYPE, mAccount.type);
11714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else {
11724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(RawContacts.ACCOUNT_NAME, null);
11734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(RawContacts.ACCOUNT_TYPE, null);
11744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
11754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        operationList.add(builder.build());
11764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (!nameFieldsAreEmpty()) {
11784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
11794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValueBackReference(StructuredName.RAW_CONTACT_ID, 0);
11804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(Data.MIMETYPE, StructuredName.CONTENT_ITEM_TYPE);
11814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(StructuredName.GIVEN_NAME, mGivenName);
11834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(StructuredName.FAMILY_NAME, mFamilyName);
11844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(StructuredName.MIDDLE_NAME, mMiddleName);
11854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(StructuredName.PREFIX, mPrefix);
11864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(StructuredName.SUFFIX, mSuffix);
11874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            if (!(TextUtils.isEmpty(mPhoneticGivenName)
11894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    && TextUtils.isEmpty(mPhoneticFamilyName)
11904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    && TextUtils.isEmpty(mPhoneticMiddleName))) {
11914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(StructuredName.PHONETIC_GIVEN_NAME, mPhoneticGivenName);
11924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(StructuredName.PHONETIC_FAMILY_NAME, mPhoneticFamilyName);
11934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(StructuredName.PHONETIC_MIDDLE_NAME, mPhoneticMiddleName);
11944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            } else if (!TextUtils.isEmpty(mPhoneticFullName)) {
11954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(StructuredName.PHONETIC_GIVEN_NAME, mPhoneticFullName);
11964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
11974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
11984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(StructuredName.DISPLAY_NAME, getDisplayName());
11994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            operationList.add(builder.build());
12004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
12014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mNickNameList != null && mNickNameList.size() > 0) {
12034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String nickName : mNickNameList) {
12044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
12054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValueBackReference(Nickname.RAW_CONTACT_ID, 0);
12064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Nickname.CONTENT_ITEM_TYPE);
12074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Nickname.TYPE, Nickname.TYPE_DEFAULT);
12084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Nickname.NAME, nickName);
12094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
12104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
12114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
12124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPhoneList != null) {
12144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (PhoneData phoneData : mPhoneList) {
12154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
12164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValueBackReference(Phone.RAW_CONTACT_ID, 0);
12174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Phone.CONTENT_ITEM_TYPE);
12184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Phone.TYPE, phoneData.type);
12204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (phoneData.type == Phone.TYPE_CUSTOM) {
12214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Phone.LABEL, phoneData.label);
12224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
12234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Phone.NUMBER, phoneData.data);
12244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (phoneData.isPrimary) {
12254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Phone.IS_PRIMARY, 1);
12264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
12274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
12284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
12294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
12304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mOrganizationList != null) {
12324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (OrganizationData organizationData : mOrganizationList) {
12334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
12344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValueBackReference(Organization.RAW_CONTACT_ID, 0);
12354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Organization.CONTENT_ITEM_TYPE);
12364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Organization.TYPE, organizationData.type);
12374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (organizationData.companyName != null) {
12384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Organization.COMPANY, organizationData.companyName);
12394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
12404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (organizationData.departmentName != null) {
12414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Organization.DEPARTMENT, organizationData.departmentName);
12424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
12434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (organizationData.titleName != null) {
12444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Organization.TITLE, organizationData.titleName);
12454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
12464560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                if (organizationData.phoneticName != null) {
12474560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                    builder.withValue(Organization.PHONETIC_NAME, organizationData.phoneticName);
12484560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa                }
12494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (organizationData.isPrimary) {
12504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Organization.IS_PRIMARY, 1);
12514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
12524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
12534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
12544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
12554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mEmailList != null) {
12574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (EmailData emailData : mEmailList) {
12584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
12594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValueBackReference(Email.RAW_CONTACT_ID, 0);
12604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Email.CONTENT_ITEM_TYPE);
12614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Email.TYPE, emailData.type);
12634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (emailData.type == Email.TYPE_CUSTOM) {
12644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Email.LABEL, emailData.label);
12654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
12664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Email.DATA, emailData.data);
12674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (emailData.isPrimary) {
12684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Data.IS_PRIMARY, 1);
12694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
12704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
12714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
12724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
12734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPostalList != null) {
12754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (PostalData postalData : mPostalList) {
12764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1277a7cff0a3bfc08867f3aa7998524f93ea5824549eDaisuke Miyakawa                builder.withValueBackReference(Event.RAW_CONTACT_ID, 0);
12784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                VCardUtils.insertStructuredPostalDataUsingContactsStruct(
12794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        mVCardType, builder, postalData);
12804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
12814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
12824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
12834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
12844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mImList != null) {
12854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (ImData imData : mImList) {
12864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
12874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValueBackReference(Im.RAW_CONTACT_ID, 0);
12884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Im.CONTENT_ITEM_TYPE);
12894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Im.TYPE, imData.type);
12904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Im.PROTOCOL, imData.protocol);
129106ae82316d0b5f7222a7a1d15b7d03df88fdea15Daisuke Miyakawa                builder.withValue(Im.DATA, imData.data);
12924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (imData.protocol == Im.PROTOCOL_CUSTOM) {
12934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Im.CUSTOM_PROTOCOL, imData.customProtocol);
12944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
12954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (imData.isPrimary) {
12964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Data.IS_PRIMARY, 1);
12974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
129806ae82316d0b5f7222a7a1d15b7d03df88fdea15Daisuke Miyakawa                operationList.add(builder.build());
12994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
13004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
13014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mNoteList != null) {
13034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String note : mNoteList) {
13044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
13054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValueBackReference(Note.RAW_CONTACT_ID, 0);
13064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Note.CONTENT_ITEM_TYPE);
13074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Note.NOTE, note);
13084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
13094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
13104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
13114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mPhotoList != null) {
13134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (PhotoData photoData : mPhotoList) {
13144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
13154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValueBackReference(Photo.RAW_CONTACT_ID, 0);
13164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Photo.CONTENT_ITEM_TYPE);
13174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Photo.PHOTO, photoData.photoBytes);
13184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (photoData.isPrimary) {
13194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.withValue(Photo.IS_PRIMARY, 1);
13204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
13214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
13224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
13234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
13244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mWebsiteList != null) {
13264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String website : mWebsiteList) {
13274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
13284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValueBackReference(Website.RAW_CONTACT_ID, 0);
13294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, Website.CONTENT_ITEM_TYPE);
13304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Website.URL, website);
13314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // There's no information about the type of URL in vCard.
13324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                // We use TYPE_HOMEPAGE for safety.
13334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.withValue(Website.TYPE, Website.TYPE_HOMEPAGE);
13344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
13354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
13364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
13374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (!TextUtils.isEmpty(mBirthday)) {
13394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
13404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValueBackReference(Event.RAW_CONTACT_ID, 0);
13414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(Data.MIMETYPE, Event.CONTENT_ITEM_TYPE);
13424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(Event.START_DATE, mBirthday);
13434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(Event.TYPE, Event.TYPE_BIRTHDAY);
13444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            operationList.add(builder.build());
13454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
13464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
1347c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa        if (!TextUtils.isEmpty(mAnniversary)) {
1348c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1349c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa            builder.withValueBackReference(Event.RAW_CONTACT_ID, 0);
1350c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa            builder.withValue(Data.MIMETYPE, Event.CONTENT_ITEM_TYPE);
135142f5f84d9d501893bc14702276f0300ca8230bb5Daisuke Miyakawa            builder.withValue(Event.START_DATE, mAnniversary);
1352c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa            builder.withValue(Event.TYPE, Event.TYPE_ANNIVERSARY);
1353c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa            operationList.add(builder.build());
1354c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa        }
1355c13101ba38c929d91dcb68e21165c82c19af35d7Daisuke Miyakawa
135637634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa        if (mSipSet != null && !mSipSet.isEmpty()) {
135737634a0179f74431317f50d2ce493e3fad36f5a9Daisuke Miyakawa            for (String sipAddress : mSipSet) {
135888d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa                builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
1359a7cff0a3bfc08867f3aa7998524f93ea5824549eDaisuke Miyakawa                builder.withValueBackReference(Event.RAW_CONTACT_ID, 0);
136088d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa                builder.withValue(Data.MIMETYPE, SipAddress.CONTENT_ITEM_TYPE);
136188d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa                builder.withValue(SipAddress.SIP_ADDRESS, sipAddress);
136288d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa                operationList.add(builder.build());
136388d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa            }
136488d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa        }
136588d0f1ef715f2e1209eba5d175b1b71c556fa8b0Daisuke Miyakawa
13664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mAndroidCustomPropertyList != null) {
13674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (List<String> customPropertyList : mAndroidCustomPropertyList) {
13684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                int size = customPropertyList.size();
13694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (size < 2 || TextUtils.isEmpty(customPropertyList.get(0))) {
13704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    continue;
13714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                } else if (size > VCardConstants.MAX_DATA_COLUMN + 1) {
13724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    size = VCardConstants.MAX_DATA_COLUMN + 1;
13734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    customPropertyList =
13744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        customPropertyList.subList(0, VCardConstants.MAX_DATA_COLUMN + 2);
13754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
13764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                int i = 0;
13784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                for (final String customPropertyValue : customPropertyList) {
13794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    if (i == 0) {
13804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        final String mimeType = customPropertyValue;
13814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
13824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        builder.withValueBackReference(GroupMembership.RAW_CONTACT_ID, 0);
13834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        builder.withValue(Data.MIMETYPE, mimeType);
13844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    } else {  // 1 <= i && i <= MAX_DATA_COLUMNS
13854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        if (!TextUtils.isEmpty(customPropertyValue)) {
13864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                            builder.withValue("data" + i, customPropertyValue);
13874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        }
13884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    }
13894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    i++;
13914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
13924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                operationList.add(builder.build());
13934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
13944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
13954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
13964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (myGroupsId != null) {
13974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder = ContentProviderOperation.newInsert(Data.CONTENT_URI);
13984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValueBackReference(GroupMembership.RAW_CONTACT_ID, 0);
13994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(Data.MIMETYPE, GroupMembership.CONTENT_ITEM_TYPE);
14004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            builder.withValue(GroupMembership.GROUP_SOURCE_ID, myGroupsId);
14014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            operationList.add(builder.build());
14024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
14034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        try {
14054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            ContentProviderResult[] results = resolver.applyBatch(
14064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                        ContactsContract.AUTHORITY, operationList);
14074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // the first result is always the raw_contact. return it's uri so
14084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // that it can be found later. do null checking for badly behaving
14094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            // ContentResolvers
14104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return (results == null || results.length == 0 || results[0] == null)
14114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                ? null
14124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                : results[0].uri;
14134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } catch (RemoteException e) {
14144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Log.e(LOG_TAG, String.format("%s: %s", e.toString(), e.getMessage()));
14154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return null;
14164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } catch (OperationApplicationException e) {
14174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            Log.e(LOG_TAG, String.format("%s: %s", e.toString(), e.getMessage()));
14184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return null;
14194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
14204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static VCardEntry buildFromResolver(ContentResolver resolver) {
14234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return buildFromResolver(resolver, Contacts.CONTENT_URI);
14244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public static VCardEntry buildFromResolver(ContentResolver resolver, Uri uri) {
14274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return null;
14294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private boolean nameFieldsAreEmpty() {
14324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return (TextUtils.isEmpty(mFamilyName)
14334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mMiddleName)
14344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mGivenName)
14354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mPrefix)
14364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mSuffix)
14374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mFormattedName)
14384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mPhoneticFamilyName)
14394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mPhoneticMiddleName)
14404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mPhoneticGivenName)
14414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                && TextUtils.isEmpty(mPhoneticFullName));
14424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public boolean isIgnorable() {
14454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return getDisplayName().length() == 0;
14464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    private String listToString(List<String> list){
14494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        final int size = list.size();
14504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (size > 1) {
14514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            StringBuilder builder = new StringBuilder();
14524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            int i = 0;
14534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            for (String type : list) {
14544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                builder.append(type);
14554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                if (i < size - 1) {
14564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                    builder.append(";");
14574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa                }
14584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            }
14594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return builder.toString();
14604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else if (size == 1) {
14614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return list.get(0);
14624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        } else {
14634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            return "";
14644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
14654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // All getter methods should be used carefully, since they may change
14684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // in the future as of 2009-10-05, on which I cannot be sure this structure
14694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // is completely consolidated.
14704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    //
14714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // Also note that these getter methods should be used only after
14724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // all properties being pushed into this object. If not, incorrect
14734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    // value will "be stored in the local cache and" be returned to you.
14744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getFamilyName() {
14764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mFamilyName;
14774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getGivenName() {
14804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mGivenName;
14814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getMiddleName() {
14844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mMiddleName;
14854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getPrefix() {
14884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPrefix;
14894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getSuffix() {
14924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mSuffix;
14934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getFullName() {
14964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mFormattedName;
14974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
14984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
14994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getPhoneticFamilyName() {
15004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPhoneticFamilyName;
15014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getPhoneticGivenName() {
15044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPhoneticGivenName;
15054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getPhoneticMiddleName() {
15084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPhoneticMiddleName;
15094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getPhoneticFullName() {
15124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPhoneticFullName;
15134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<String> getNickNameList() {
15164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mNickNameList;
15174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getBirthday() {
15204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mBirthday;
15214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<String> getNotes() {
15244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mNoteList;
15254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<PhoneData> getPhoneList() {
15284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPhoneList;
15294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<EmailData> getEmailList() {
15324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mEmailList;
15334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<PostalData> getPostalList() {
15364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPostalList;
15374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<OrganizationData> getOrganizationList() {
15404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mOrganizationList;
15414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<ImData> getImList() {
15444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mImList;
15454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<PhotoData> getPhotoList() {
15484199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mPhotoList;
15494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public final List<String> getWebsiteList() {
15524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mWebsiteList;
15534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa
15554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    public String getDisplayName() {
15564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        if (mDisplayName == null) {
15574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa            constructDisplayName();
15584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        }
15594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa        return mDisplayName;
15604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa    }
15614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa}
1562