1e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng/* 2e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * Copyright (C) 2011 The Android Open Source Project 3e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * 4e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * Licensed under the Apache License, Version 2.0 (the "License"); 5e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * you may not use this file except in compliance with the License. 6e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * You may obtain a copy of the License at 7e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * 8e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * http://www.apache.org/licenses/LICENSE-2.0 9e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * 10e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * Unless required by applicable law or agreed to in writing, software 11e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * distributed under the License is distributed on an "AS IS" BASIS, 12e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * See the License for the specific language governing permissions and 14e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * limitations under the License. 15e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng */ 16e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 1769c182afb0e6d82a341a28b4317aa703af768906Gary Maipackage com.android.contacts.model.account; 18e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 19e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Chengimport android.accounts.Account; 20a75206b1cba895ce629b9383e4fd0fef24049e7bMarcus Hagerottimport android.content.ContentProviderOperation; 21e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Chengimport android.content.Context; 22e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Chengimport android.database.Cursor; 23e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Chengimport android.net.Uri; 24e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Chengimport android.os.Parcel; 25819214d472fdadf3d69cb4580e238506194ed30eMarcus Hagerottimport android.os.Parcelable; 26e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Chengimport android.provider.BaseColumns; 27e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Chengimport android.provider.ContactsContract; 28e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Chengimport android.provider.ContactsContract.RawContacts; 29e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Chengimport android.text.TextUtils; 30e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 3169c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.model.AccountTypeManager; 3269c182afb0e6d82a341a28b4317aa703af768906Gary Maiimport com.android.contacts.preference.ContactsPreferences; 3341ba9e52de4f7ef962e6105095030f44fb9d6fefChiao Chengimport com.google.common.base.Objects; 34e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Chengimport com.google.common.collect.Lists; 35e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 36e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Chengimport java.util.ArrayList; 37e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Chengimport java.util.List; 38e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Chengimport java.util.regex.Pattern; 39e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 40e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng/** 41e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * Wrapper for an account that includes a data set (which may be null). 42e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng */ 432ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shraunerpublic class AccountWithDataSet implements Parcelable { 44e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng private static final String STRINGIFY_SEPARATOR = "\u0001"; 45e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng private static final String ARRAY_STRINGIFY_SEPARATOR = "\u0002"; 46e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 47e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng private static final Pattern STRINGIFY_SEPARATOR_PAT = 48e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng Pattern.compile(Pattern.quote(STRINGIFY_SEPARATOR)); 49e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng private static final Pattern ARRAY_STRINGIFY_SEPARATOR_PAT = 50e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng Pattern.compile(Pattern.quote(ARRAY_STRINGIFY_SEPARATOR)); 51e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 522ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner public final String name; 532ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner public final String type; 54e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng public final String dataSet; 55e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng private final AccountTypeWithDataSet mAccountTypeWithDataSet; 56e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 57e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng private static final String[] ID_PROJECTION = new String[] {BaseColumns._ID}; 58e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng private static final Uri RAW_CONTACTS_URI_LIMIT_1 = RawContacts.CONTENT_URI.buildUpon() 59e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng .appendQueryParameter(ContactsContract.LIMIT_PARAM_KEY, "1").build(); 60e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 610ac73ba01aa1f9fc9cc2cc23703cf6c24e40f488Tingting Wang public static final String LOCAL_ACCOUNT_SELECTION = RawContacts.ACCOUNT_TYPE + " IS NULL AND " 620ac73ba01aa1f9fc9cc2cc23703cf6c24e40f488Tingting Wang + RawContacts.ACCOUNT_NAME + " IS NULL AND " 630ac73ba01aa1f9fc9cc2cc23703cf6c24e40f488Tingting Wang + RawContacts.DATA_SET + " IS NULL"; 64e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 65e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng public AccountWithDataSet(String name, String type, String dataSet) { 662ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner this.name = emptyToNull(name); 672ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner this.type = emptyToNull(type); 682ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner this.dataSet = emptyToNull(dataSet); 69e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng mAccountTypeWithDataSet = AccountTypeWithDataSet.get(type, dataSet); 70e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 71e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 722ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner private static final String emptyToNull(String text) { 732ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner return TextUtils.isEmpty(text) ? null : text; 742ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner } 752ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner 76e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng public AccountWithDataSet(Parcel in) { 772ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner this.name = in.readString(); 782ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner this.type = in.readString(); 79e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng this.dataSet = in.readString(); 80e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng mAccountTypeWithDataSet = AccountTypeWithDataSet.get(type, dataSet); 81e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 82e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 83949d4e88400761dac02992978f6b79997b5f0055Marcus Hagerott public boolean isNullAccount() { 840ac73ba01aa1f9fc9cc2cc23703cf6c24e40f488Tingting Wang return name == null && type == null && dataSet == null; 850ac73ba01aa1f9fc9cc2cc23703cf6c24e40f488Tingting Wang } 860ac73ba01aa1f9fc9cc2cc23703cf6c24e40f488Tingting Wang 87949d4e88400761dac02992978f6b79997b5f0055Marcus Hagerott public static AccountWithDataSet getNullAccount() { 880ac73ba01aa1f9fc9cc2cc23703cf6c24e40f488Tingting Wang return new AccountWithDataSet(null, null, null); 892ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner } 902ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner 912ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner public Account getAccountOrNull() { 922ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner if (name != null && type != null) { 932ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner return new Account(name, type); 942ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner } 952ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner return null; 962ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner } 972ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner 982ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner public int describeContents() { 992ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner return 0; 1002ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner } 1012ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner 102e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng public void writeToParcel(Parcel dest, int flags) { 1032ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner dest.writeString(name); 1042ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner dest.writeString(type); 105e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng dest.writeString(dataSet); 106e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 107e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 108e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng // For Parcelable 109e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng public static final Creator<AccountWithDataSet> CREATOR = new Creator<AccountWithDataSet>() { 110e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng public AccountWithDataSet createFromParcel(Parcel source) { 111e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng return new AccountWithDataSet(source); 112e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 113e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 114e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng public AccountWithDataSet[] newArray(int size) { 115e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng return new AccountWithDataSet[size]; 116e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 117e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng }; 118e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 119e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng public AccountTypeWithDataSet getAccountTypeWithDataSet() { 120e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng return mAccountTypeWithDataSet; 121e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 122e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 123e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng /** 124e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * Return {@code true} if this account has any contacts in the database. 125e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * Touches DB. Don't use in the UI thread. 126e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng */ 127e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng public boolean hasData(Context context) { 1280ac73ba01aa1f9fc9cc2cc23703cf6c24e40f488Tingting Wang String selection; 1290ac73ba01aa1f9fc9cc2cc23703cf6c24e40f488Tingting Wang String[] args = null; 130949d4e88400761dac02992978f6b79997b5f0055Marcus Hagerott if (isNullAccount()) { 1310ac73ba01aa1f9fc9cc2cc23703cf6c24e40f488Tingting Wang selection = LOCAL_ACCOUNT_SELECTION; 132e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } else { 1330ac73ba01aa1f9fc9cc2cc23703cf6c24e40f488Tingting Wang final String BASE_SELECTION = 1340ac73ba01aa1f9fc9cc2cc23703cf6c24e40f488Tingting Wang RawContacts.ACCOUNT_TYPE + " = ?" + " AND " + RawContacts.ACCOUNT_NAME + " = ?"; 1350ac73ba01aa1f9fc9cc2cc23703cf6c24e40f488Tingting Wang if (TextUtils.isEmpty(dataSet)) { 1360ac73ba01aa1f9fc9cc2cc23703cf6c24e40f488Tingting Wang selection = BASE_SELECTION + " AND " + RawContacts.DATA_SET + " IS NULL"; 1370ac73ba01aa1f9fc9cc2cc23703cf6c24e40f488Tingting Wang args = new String[] {type, name}; 1380ac73ba01aa1f9fc9cc2cc23703cf6c24e40f488Tingting Wang } else { 1390ac73ba01aa1f9fc9cc2cc23703cf6c24e40f488Tingting Wang selection = BASE_SELECTION + " AND " + RawContacts.DATA_SET + " = ?"; 1400ac73ba01aa1f9fc9cc2cc23703cf6c24e40f488Tingting Wang args = new String[] {type, name, dataSet}; 1410ac73ba01aa1f9fc9cc2cc23703cf6c24e40f488Tingting Wang } 142e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 143bc5108495a35010073b925f9c7e04ee35fe1120eMarcus Hagerott selection += " AND " + RawContacts.DELETED + "=0"; 144e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 145e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng final Cursor c = context.getContentResolver().query(RAW_CONTACTS_URI_LIMIT_1, 146e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng ID_PROJECTION, selection, args, null); 147e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng if (c == null) return false; 148e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng try { 149e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng return c.moveToFirst(); 150e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } finally { 151e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng c.close(); 152e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 153e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 154e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 1552ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner public boolean equals(Object obj) { 1562ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner if (obj instanceof AccountWithDataSet) { 1572ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner AccountWithDataSet other = (AccountWithDataSet) obj; 1582ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner return Objects.equal(name, other.name) 1592ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner && Objects.equal(type, other.type) 1602ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner && Objects.equal(dataSet, other.dataSet); 1612ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner } 1622ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner return false; 163e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 164e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 165e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng public int hashCode() { 1662ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner int result = 17; 1672ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner result = 31 * result + (name != null ? name.hashCode() : 0); 1682ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner result = 31 * result + (type != null ? type.hashCode() : 0); 1692ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner result = 31 * result + (dataSet != null ? dataSet.hashCode() : 0); 1702ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner return result; 171e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 172e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 173e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng public String toString() { 174e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng return "AccountWithDataSet {name=" + name + ", type=" + type + ", dataSet=" + dataSet + "}"; 175e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 176e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 177e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng private static StringBuilder addStringified(StringBuilder sb, AccountWithDataSet account) { 1782ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner if (!TextUtils.isEmpty(account.name)) sb.append(account.name); 179e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng sb.append(STRINGIFY_SEPARATOR); 1802ae200dc7b2995f6758887cce8dedf563b3f3aa3Jay Shrauner if (!TextUtils.isEmpty(account.type)) sb.append(account.type); 181e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng sb.append(STRINGIFY_SEPARATOR); 182e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng if (!TextUtils.isEmpty(account.dataSet)) sb.append(account.dataSet); 183e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 184e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng return sb; 185e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 186e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 187e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng /** 188e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * Pack the instance into a string. 189e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng */ 190e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng public String stringify() { 191e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng return addStringified(new StringBuilder(), this).toString(); 192e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 193e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 194e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng /** 195a75206b1cba895ce629b9383e4fd0fef24049e7bMarcus Hagerott * Returns a {@link ContentProviderOperation} that will create a RawContact in this account 196a75206b1cba895ce629b9383e4fd0fef24049e7bMarcus Hagerott */ 197a75206b1cba895ce629b9383e4fd0fef24049e7bMarcus Hagerott public ContentProviderOperation newRawContactOperation() { 198a75206b1cba895ce629b9383e4fd0fef24049e7bMarcus Hagerott final ContentProviderOperation.Builder builder = 199a75206b1cba895ce629b9383e4fd0fef24049e7bMarcus Hagerott ContentProviderOperation.newInsert(RawContacts.CONTENT_URI) 200a75206b1cba895ce629b9383e4fd0fef24049e7bMarcus Hagerott .withValue(RawContacts.ACCOUNT_NAME, name) 201a75206b1cba895ce629b9383e4fd0fef24049e7bMarcus Hagerott .withValue(RawContacts.ACCOUNT_TYPE, type); 202a75206b1cba895ce629b9383e4fd0fef24049e7bMarcus Hagerott if (dataSet != null) { 203a75206b1cba895ce629b9383e4fd0fef24049e7bMarcus Hagerott builder.withValue(RawContacts.DATA_SET, dataSet); 204a75206b1cba895ce629b9383e4fd0fef24049e7bMarcus Hagerott } 205a75206b1cba895ce629b9383e4fd0fef24049e7bMarcus Hagerott return builder.build(); 206a75206b1cba895ce629b9383e4fd0fef24049e7bMarcus Hagerott } 207a75206b1cba895ce629b9383e4fd0fef24049e7bMarcus Hagerott 208a75206b1cba895ce629b9383e4fd0fef24049e7bMarcus Hagerott /** 209e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * Unpack a string created by {@link #stringify}. 210e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * 211e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * @throws IllegalArgumentException if it's an invalid string. 212e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng */ 213e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng public static AccountWithDataSet unstringify(String s) { 214e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng final String[] array = STRINGIFY_SEPARATOR_PAT.split(s, 3); 215e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng if (array.length < 3) { 216e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng throw new IllegalArgumentException("Invalid string " + s); 217e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 218e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng return new AccountWithDataSet(array[0], array[1], 219e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng TextUtils.isEmpty(array[2]) ? null : array[2]); 220e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 221e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 222e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng /** 223e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * Pack a list of {@link AccountWithDataSet} into a string. 224e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng */ 225e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng public static String stringifyList(List<AccountWithDataSet> accounts) { 226e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng final StringBuilder sb = new StringBuilder(); 227e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 228e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng for (AccountWithDataSet account : accounts) { 229e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng if (sb.length() > 0) { 230e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng sb.append(ARRAY_STRINGIFY_SEPARATOR); 231e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 232e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng addStringified(sb, account); 233e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 234e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 235e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng return sb.toString(); 236e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 237e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 238e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng /** 239e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * Unpack a list of {@link AccountWithDataSet} into a string. 240e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * 241e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng * @throws IllegalArgumentException if it's an invalid string. 242e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng */ 243e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng public static List<AccountWithDataSet> unstringifyList(String s) { 244e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng final ArrayList<AccountWithDataSet> ret = Lists.newArrayList(); 245e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng if (TextUtils.isEmpty(s)) { 246e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng return ret; 247e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 248e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 249e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng final String[] array = ARRAY_STRINGIFY_SEPARATOR_PAT.split(s); 250e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 251e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng for (int i = 0; i < array.length; i++) { 252e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng ret.add(unstringify(array[i])); 253e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 254e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng 255e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng return ret; 256e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng } 257e88fcd3e82377aa3579ddf98389b6e20bae34c07Chiao Cheng} 258f0e140aec2f5832a517243084bea626011be9c39Marcus Hagerott 259