14199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa/* 24199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Copyright (C) 2010 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 */ 16677ef21613a9d35053ec098444832ce4125a847eDaisuke Miyakawapackage com.android.vcard.tests.testutils; 174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.content.ContentProviderOperation; 194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.content.ContentProviderResult; 204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.content.ContentValues; 214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.net.Uri; 225f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawaimport android.provider.ContactsContract.Data; 235f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawaimport android.provider.ContactsContract.RawContacts; 244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.test.mock.MockContentProvider; 254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport android.text.TextUtils; 264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport junit.framework.TestCase; 284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.ArrayList; 304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Arrays; 314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Collection; 324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.HashMap; 334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.HashSet; 344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Map; 355f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawaimport java.util.Map.Entry; 364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.Set; 374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.SortedMap; 384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawaimport java.util.TreeMap; 394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 401680191a2a208fd61123810a88ce9def83e222baDaisuke Miyakawapublic class ImportTestProvider extends MockContentProvider { 411de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa private final Map<String, Collection<ContentValues>> 421de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa mMimeTypeToExpectedContentValues = new HashMap<String, Collection<ContentValues>>(); 434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public void addExpectedContentValues(ContentValues expectedContentValues) { 454199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa final String mimeType = expectedContentValues.getAsString(Data.MIMETYPE); 461de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa 471de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa final Collection<ContentValues> contentValuesCollection; 481de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa if (mMimeTypeToExpectedContentValues.containsKey(mimeType)) { 491de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa contentValuesCollection = mMimeTypeToExpectedContentValues.get(mimeType); 501de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa } else { 511de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa contentValuesCollection = new ArrayList<ContentValues>(); 521de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa mMimeTypeToExpectedContentValues.put(mimeType, contentValuesCollection); 534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 544199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 554199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa contentValuesCollection.add(expectedContentValues); 564199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa @Override 594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public ContentProviderResult[] applyBatch( 604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa ArrayList<ContentProviderOperation> operations) { 614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (operations == null) { 625f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa TestCase.fail("There is no operation."); 634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa final int size = operations.size(); 664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa ContentProviderResult[] fakeResultArray = new ContentProviderResult[size]; 674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa for (int i = 0; i < size; i++) { 684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa Uri uri = Uri.withAppendedPath(RawContacts.CONTENT_URI, String.valueOf(i)); 694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa fakeResultArray[i] = new ContentProviderResult(uri); 704199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa for (int i = 0; i < size; i++) { 734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa ContentProviderOperation operation = operations.get(i); 744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa ContentValues contentValues = operation.resolveValueBackReferences( 754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa fakeResultArray, i); 764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa for (int i = 0; i < size; i++) { 784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa ContentProviderOperation operation = operations.get(i); 794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa ContentValues actualContentValues = operation.resolveValueBackReferences( 804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa fakeResultArray, i); 814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa final Uri uri = operation.getUri(); 824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (uri.equals(RawContacts.CONTENT_URI)) { 835f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa TestCase.assertNull(actualContentValues.get(RawContacts.ACCOUNT_NAME)); 845f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa TestCase.assertNull(actualContentValues.get(RawContacts.ACCOUNT_TYPE)); 854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else if (uri.equals(Data.CONTENT_URI)) { 864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa final String mimeType = actualContentValues.getAsString(Data.MIMETYPE); 871de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa if (!mMimeTypeToExpectedContentValues.containsKey(mimeType)) { 881de396f6df89363169d3a2e61a61fa98d12c1ef8Daisuke Miyakawa TestCase.fail("Unregistered MimeType " + mimeType); 894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 904199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // Remove data meaningless in this unit tests. 914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // Specifically, Data.DATA1 - DATA7 are set to null or empty String 924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // regardless of the input, but it may change depending on how 934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // resolver-related code handles it. 944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // Here, we ignore these implementation-dependent specs and 954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // just check whether vCard importer correctly inserts rellevent data. 964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa Set<String> keyToBeRemoved = new HashSet<String>(); 974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa for (Entry<String, Object> entry : actualContentValues.valueSet()) { 984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa Object value = entry.getValue(); 994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (value == null || TextUtils.isEmpty(value.toString())) { 1004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa keyToBeRemoved.add(entry.getKey()); 1014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa for (String key: keyToBeRemoved) { 1044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa actualContentValues.remove(key); 1054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa /* for testing 1074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa Log.d("@@@", 1084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa String.format("MimeType: %s, data: %s", 1094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mimeType, actualContentValues.toString())); */ 1104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // Remove RAW_CONTACT_ID entry just for safety, since we do not care 1114199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa // how resolver-related code handles the entry in this unit test, 1124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (actualContentValues.containsKey(Data.RAW_CONTACT_ID)) { 1134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa actualContentValues.remove(Data.RAW_CONTACT_ID); 1144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa final Collection<ContentValues> contentValuesCollection = 1164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mMimeTypeToExpectedContentValues.get(mimeType); 1174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (contentValuesCollection.isEmpty()) { 1185f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa TestCase.fail("ContentValues for MimeType " + mimeType 1194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa + " is not expected at all (" + actualContentValues + ")"); 1204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa boolean checked = false; 1224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa for (ContentValues expectedContentValues : contentValuesCollection) { 1234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa /*for testing 1244199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa Log.d("@@@", "expected: " 1254199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa + convertToEasilyReadableString(expectedContentValues)); 1264199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa Log.d("@@@", "actual : " 1274199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa + convertToEasilyReadableString(actualContentValues));*/ 1284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (equalsForContentValues(expectedContentValues, 1294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa actualContentValues)) { 1305f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa TestCase.assertTrue(contentValuesCollection.remove(expectedContentValues)); 1314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa checked = true; 1324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa break; 1334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1344199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1354199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (!checked) { 1364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa final StringBuilder builder = new StringBuilder(); 1374560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa builder.append("\n"); 1384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append("Unexpected: "); 1394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(convertToEasilyReadableString(actualContentValues)); 1404560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa builder.append("\n"); 1414560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa builder.append("Expected : "); 1424199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa for (ContentValues expectedContentValues : contentValuesCollection) { 1434199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(convertToEasilyReadableString(expectedContentValues)); 1444199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1455f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa TestCase.fail(builder.toString()); 1464199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1474199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else { 1485f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa TestCase.fail("Unexpected Uri has come: " + uri); 1494199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1504199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } // for (int i = 0; i < size; i++) { 1514199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return fakeResultArray; 1524199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1534199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 15448dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa /** 15548dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa * Checks all expected ContentValues are consumed during import. 15648dd8e86a81d2ab40eb762975c8211c225002bf0Daisuke Miyakawa */ 1574199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa public void verify() { 1584199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa StringBuilder builder = new StringBuilder(); 1594199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa for (Collection<ContentValues> contentValuesCollection : 1604199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mMimeTypeToExpectedContentValues.values()) { 1614199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa for (ContentValues expectedContentValues: contentValuesCollection) { 1624199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(convertToEasilyReadableString(expectedContentValues)); 1634199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append("\n"); 1644199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1654199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1664199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (builder.length() > 0) { 1674199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa final String failMsg = 1684199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa "There is(are) remaining expected ContentValues instance(s): \n" 1694199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa + builder.toString(); 1705f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa TestCase.fail(failMsg); 1714199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1724199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1734199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 1744199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa /** 1754199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa * Utility method to print ContentValues whose content is printed with sorted keys. 1764199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa */ 1774199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private String convertToEasilyReadableString(ContentValues contentValues) { 1784199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (contentValues == null) { 1794199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return "null"; 1804199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1814199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa String mimeTypeValue = ""; 1824199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa SortedMap<String, String> sortedMap = new TreeMap<String, String>(); 1834199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa for (Entry<String, Object> entry : contentValues.valueSet()) { 1844199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa final String key = entry.getKey(); 1854199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa final Object value = entry.getValue(); 1864199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa final String valueString = (value != null ? value.toString() : null); 1874199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (Data.MIMETYPE.equals(key)) { 1884199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa mimeTypeValue = valueString; 1894199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else { 1905f363a8136349b242d243c3c0c14e6d5a065d23fDaisuke Miyakawa TestCase.assertNotNull(key); 1914199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa sortedMap.put(key, valueString); 1924199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1934199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 1944199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa StringBuilder builder = new StringBuilder(); 1954199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(Data.MIMETYPE); 1964199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append('='); 1974199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(mimeTypeValue); 1984199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa for (Entry<String, String> entry : sortedMap.entrySet()) { 1994199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa final String key = entry.getKey(); 2004199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa final String value = entry.getValue(); 2014199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(' '); 2024199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(key); 2034199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append("=\""); 2044199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append(value); 2054199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa builder.append('"'); 2064199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2074199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return builder.toString(); 2084199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2094199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 2104199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa private static boolean equalsForContentValues( 2114560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa final ContentValues expected, final ContentValues actual) { 2124199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (expected == actual) { 2134199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return true; 2144199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } else if (expected == null || actual == null || expected.size() != actual.size()) { 2154199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return false; 2164199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2174199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa 2184199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa for (Entry<String, Object> entry : expected.valueSet()) { 2194199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa final String key = entry.getKey(); 2204199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa final Object value = entry.getValue(); 2214199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (!actual.containsKey(key)) { 2224199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return false; 2234199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2244560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa // Type mismatch usuall happens as importer doesn't care the type of each value. 2254560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa // For example, variable type might be Integer when importing the type of TEL, 2264560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa // while variable type would be String when importing the type of RELATION. 2274560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa final Object actualValue = actual.get(key); 2284199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (value instanceof byte[]) { 2294199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa if (!Arrays.equals((byte[])value, (byte[])actualValue)) { 2304199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa byte[] e = (byte[])value; 2314199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa byte[] a = (byte[])actualValue; 2324199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return false; 2334199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2344560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa } else if (!value.equals(actualValue) && 2354560bdde6dd75cca49fc55b58aafb5d416b88ca3Daisuke Miyakawa !value.toString().equals(actualValue.toString())) { 2364199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return false; 2374199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2384199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2394199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa return true; 2404199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa } 2414199c54c527330ac01699b176e7bca186a3aa3a4Daisuke Miyakawa}