/* * CDDL HEADER START * * The contents of this file are subject to the terms of the Common Development * and Distribution License (the "License"). * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at * src/com/vodafone360/people/VODAFONE.LICENSE.txt or * http://github.com/360/360-Engine-for-Android * See the License for the specific language governing permissions and * limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each file and * include the License file at src/com/vodafone360/people/VODAFONE.LICENSE.txt. * If applicable, add the following below this CDDL HEADER, with the fields * enclosed by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * Copyright 2010 Vodafone Sales & Services Ltd. All rights reserved. * Use is subject to license terms. */ package com.vodafone360.people.tests.engine.contactsync; import java.util.ArrayList; import java.util.Calendar; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Random; import android.text.TextUtils; import android.util.Log; import com.vodafone360.people.datatypes.VCardHelper; import com.vodafone360.people.datatypes.VCardHelper.Name; import com.vodafone360.people.datatypes.VCardHelper.Organisation; import com.vodafone360.people.datatypes.VCardHelper.PostalAddress; import com.vodafone360.people.engine.contactsync.ContactChange; import com.vodafone360.people.utils.VersionUtils; public class ContactChangeHelper { private static final int MAX_PHONE_NUMBERS_PER_CONTACT = 5; private static final int MAX_EMAILS_PER_CONTACT = 5; private static final int MAX_ADDRESSES_PER_CONTACT = 3; private static final int MAX_ORGS_PER_CONTACT = 1; private static final int MAX_TITLES_PER_CONTACT = 1; private static final int MAX_WEBSITES_PER_CONTACT = 1; private static final int MAX_BIRTHDAYS_PER_CONTACT = 1; private static final int MAX_NOTES_PER_CONTACT = 1; private static final int MAX_NAMES_PER_CONTACT = 1; private static final int MAX_NICKNAMES_PER_CONTACT = 1; private static final int MAX_NUM_DETAILS_ADD = 10; private static final HashMap<Integer, Integer> sKeyMaxNumMap; private static final int[] sKeyArray; static { sKeyArray = new int[9]; sKeyArray[0] = ContactChange.KEY_VCARD_NAME; sKeyArray[1] = ContactChange.KEY_VCARD_NICKNAME; sKeyArray[2] = ContactChange.KEY_VCARD_PHONE; sKeyArray[3] = ContactChange.KEY_VCARD_EMAIL; sKeyArray[4] = ContactChange.KEY_VCARD_ADDRESS; sKeyArray[5] = ContactChange.KEY_VCARD_ORG; sKeyArray[6] = ContactChange.KEY_VCARD_TITLE; sKeyArray[7] = ContactChange.KEY_VCARD_URL; sKeyArray[8] = ContactChange.KEY_VCARD_NOTE; sKeyMaxNumMap = new HashMap<Integer, Integer>(); sKeyMaxNumMap.put(ContactChange.KEY_VCARD_NAME, MAX_NAMES_PER_CONTACT); sKeyMaxNumMap.put(ContactChange.KEY_VCARD_NICKNAME, MAX_NICKNAMES_PER_CONTACT); sKeyMaxNumMap.put(ContactChange.KEY_VCARD_PHONE, MAX_PHONE_NUMBERS_PER_CONTACT); sKeyMaxNumMap.put(ContactChange.KEY_VCARD_EMAIL, MAX_EMAILS_PER_CONTACT); sKeyMaxNumMap.put(ContactChange.KEY_VCARD_ADDRESS, MAX_ADDRESSES_PER_CONTACT); sKeyMaxNumMap.put(ContactChange.KEY_VCARD_ORG, MAX_ORGS_PER_CONTACT); sKeyMaxNumMap.put(ContactChange.KEY_VCARD_TITLE, MAX_TITLES_PER_CONTACT); sKeyMaxNumMap.put(ContactChange.KEY_VCARD_URL, MAX_WEBSITES_PER_CONTACT); sKeyMaxNumMap.put(ContactChange.KEY_VCARD_NOTE, MAX_NOTES_PER_CONTACT); } private static Random sRn = new Random(); private static final String[] mNameTitleList = { "Mr.", "Mrs.", "Miss", "Prof.", "Dr.", "Eng." }; public static void printContactChange(ContactChange cc) { Log.i("CC", "--------------- START ---------------"); Log.d("CC", "Key:"+cc.getKeyToString()+"("+cc.getKey()+")\n"+ "Value:"+cc.getValue()+"\n"+ "Flags:"+cc.getFlags()+"\n"+ "Type:"+cc.getType()+"\n"+ "IDS(IntCntID:"+cc.getInternalContactId()+ ", IntDtlID:"+cc.getInternalDetailId()+ ", BckndCntID:"+cc.getBackendContactId()+ ", BckndDtlID:"+cc.getBackendDetailId()+ ", NABCntID:"+cc.getNabContactId()+ ", NABDtlID:"+cc.getNabDetailId()+")"); Log.i("CC", "--------------- END --------------"); } public static void printContactChangeList(ContactChange[] ccList) { final int length = ccList.length; Log.i("CCLIST", "############### START ###############"); for(int i = 0; i < length; i++) { final ContactChange cc = ccList[i]; printContactChange(cc); } Log.i("CCLIST", "############### END ###############"); } public static boolean areChangesEqual(ContactChange a, ContactChange b, boolean compareAll) { if(a.getKey() != b.getKey()) { return false; } // just for convenience final int key = a.getKey(); if(!VersionUtils.is2XPlatform() && key == ContactChange.KEY_VCARD_NAME) { // Need to convert to raw string or else we can't compare them because of NAB 1.X limitations final Name nameA = VCardHelper.getName(a.getValue()); final Name nameB = VCardHelper.getName(b.getValue()); final String nameAStr = nameA.toString(); final String nameBStr = nameB.toString(); if(!TextUtils.equals(nameAStr, nameBStr)) { return false; } } else if(!VersionUtils.is2XPlatform() && key == ContactChange.KEY_VCARD_ADDRESS) { // Need to convert to raw string or else we can't compare them because of NAB 1.X limitations final PostalAddress addressA = VCardHelper.getPostalAddress(a.getValue()); final PostalAddress addressB = VCardHelper.getPostalAddress(b.getValue()); // Need to also remove \n's that were put there by .toString final String addressAStr = addressA.toString().replaceAll("\n", ""); final String addressBStr = addressB.toString().replaceAll("\n", ""); if(!TextUtils.equals(addressAStr, addressBStr)) { return false; } } else if(!VersionUtils.is2XPlatform() && key == ContactChange.KEY_VCARD_ORG) { // Org on 1.X does not support department, need to NOT compare that final Organisation orgA = VCardHelper.getOrg(a.getValue()); final Organisation orgB = VCardHelper.getOrg(b.getValue()); if(!TextUtils.equals(orgA.name, orgB.name)) { return false; } } else if(!TextUtils.equals(a.getValue(), b.getValue())) { return false; } switch(key) { case ContactChange.KEY_VCARD_ORG: case ContactChange.KEY_VCARD_TITLE: case ContactChange.KEY_VCARD_PHONE: case ContactChange.KEY_VCARD_EMAIL: case ContactChange.KEY_VCARD_ADDRESS: // NAB may have changed these fields to preferred even though they were inserted as not preferred! final int flagsWithoutPreferredA = a.getFlags() & ~ContactChange.FLAG_PREFERRED; final int flagsWithoutPreferredB = b.getFlags() & ~ContactChange.FLAG_PREFERRED; if(flagsWithoutPreferredA != flagsWithoutPreferredB) { return false; } break; default: if(a.getFlags() != b.getFlags()) { return false; } break; } if(VersionUtils.is2XPlatform() && a.getFlags() != b.getFlags()) { return false; } else if(!VersionUtils.is2XPlatform()) { } if(compareAll) { if(a.getType() != b.getType()) { return false; } if(a.getInternalContactId() != b.getInternalContactId()) { return false; } if(a.getInternalDetailId() != b.getInternalDetailId()) { return false; } if(a.getBackendContactId() != b.getBackendContactId()) { return false; } if(a.getBackendDetailId() != b.getBackendDetailId()) { return false; } if(a.getNabContactId() != b.getNabContactId()) { return false; } if(a.getNabDetailId() != b.getNabDetailId()) { return false; } } return true; } public static boolean areChangeListsEqual(ContactChange[] a, ContactChange[] b, boolean compareAll) { final int aLength = a.length; final int bLength = b.length; if(aLength != bLength) { printContactChangeList(a); printContactChangeList(b); return false; } for(int i = 0; i < aLength; i++) { final ContactChange ccA = a[i]; final ContactChange ccB = b[i]; if(!areChangesEqual(ccA, ccB, compareAll)) { Log.e("CC COMPARISON", "Contact Change comparison mismatch, ContactChange A to follow:"); printContactChange(ccA); Log.e("CC COMPARISON", "Contact Change comparison mismatch, ContactChange B to follow:"); printContactChange(ccB); return false; } } return true; } public static boolean areUnsortedChangeListsEqual(ContactChange[] a, ContactChange[] b, boolean compareAll) { final int aLength = a.length; final int bLength = b.length; if(aLength != bLength) { printContactChangeList(a); printContactChangeList(b); return false; } for(int i = 0; i < aLength; i++) { final ContactChange ccA = a[i]; boolean matchFound = false; for(int j = 0; j < bLength; j++) { final ContactChange ccB = a[j]; if(ccA.getKey() == ccB.getKey() && ccA.getNabDetailId() == ccB.getNabDetailId()) { if(areChangesEqual(ccA, ccB, compareAll)) { matchFound = true; break; } } } if(!matchFound) { Log.e("CONTACT COMPARISON", "Contact List Unsorted comparison because of mismatch, List A to follow:"); printContactChangeList(a); Log.e("CONTACT COMPARISON", "Contact List Unsorted comparison because of mismatch, List B to follow:"); printContactChangeList(b); return false; } } return true; } public static boolean isUniqueKeyForContact(int key) { final Integer maxNum = sKeyMaxNumMap.get(key); return maxNum != null && maxNum == 1; } public static ContactChange[] randomContact(long internalContactId, long backendContactId, long nabContactId) { final List<ContactChange> ccList = new ArrayList<ContactChange>(); int numNames = 0, numNicknames = 0, numEmails = 0, numPhones = 0, numAddresses = 0, numTitles = 0, numWebsites = 0, numNotes = 0, numOrgs = 0, numBirthdays = 0; numNames = valueForLikelihoodPercentage(85, MAX_NAMES_PER_CONTACT); // 85% likely if(VersionUtils.is2XPlatform()) { numNicknames = valueForLikelihoodPercentage(30, MAX_NICKNAMES_PER_CONTACT); // 30% likely numBirthdays = valueForLikelihoodPercentage(25, MAX_BIRTHDAYS_PER_CONTACT); // 25% likely } numEmails = randomPositiveInt(MAX_EMAILS_PER_CONTACT); // Always create at least a phone number so that an empty cc list is not possible numPhones = 1 + randomPositiveInt(MAX_PHONE_NUMBERS_PER_CONTACT -1); numAddresses = randomPositiveInt(MAX_ADDRESSES_PER_CONTACT); numTitles = valueForLikelihoodPercentage(40, MAX_TITLES_PER_CONTACT); if(VersionUtils.is2XPlatform()) { numWebsites = valueForLikelihoodPercentage(35, MAX_WEBSITES_PER_CONTACT); } numNotes = valueForLikelihoodPercentage(35, MAX_NOTES_PER_CONTACT); // 35% likely numOrgs = valueForLikelihoodPercentage(40, MAX_ORGS_PER_CONTACT); generateRandomChangesForKey(ccList, ContactChange.KEY_VCARD_NAME, internalContactId, backendContactId, nabContactId, numNames); generateRandomChangesForKey(ccList, ContactChange.KEY_VCARD_NOTE, internalContactId, backendContactId, nabContactId, numNotes); generateRandomChangesForKey(ccList, ContactChange.KEY_VCARD_NICKNAME, internalContactId, backendContactId, nabContactId, numNicknames); generateRandomChangesForKey(ccList, ContactChange.KEY_VCARD_PHONE, internalContactId, backendContactId, nabContactId, numPhones); generateRandomChangesForKey(ccList, ContactChange.KEY_VCARD_EMAIL, internalContactId, backendContactId, nabContactId, numEmails); generateRandomChangesForKey(ccList, ContactChange.KEY_VCARD_DATE, internalContactId, backendContactId, nabContactId, numBirthdays); generateRandomChangesForKey(ccList, ContactChange.KEY_VCARD_ADDRESS, internalContactId, backendContactId, nabContactId, numAddresses); generateRandomChangesForKey(ccList, ContactChange.KEY_VCARD_URL, internalContactId, backendContactId, nabContactId, numWebsites); generateRandomChangesForKey(ccList, ContactChange.KEY_VCARD_ORG, internalContactId, backendContactId, nabContactId, numOrgs); generateRandomChangesForKey(ccList, ContactChange.KEY_VCARD_TITLE, internalContactId, backendContactId, nabContactId, numTitles); final int numOrgTitlePairs = Math.min(numOrgs, numTitles); if(numOrgTitlePairs > 0) { final int ccListSize = ccList.size(); // Have to make the flags for each pair have the same values so that comparison is safe later for(int i = 0; i < numOrgTitlePairs; i++) { // get org flags final int orgFlags = ccList.get((ccListSize - (numOrgs + numTitles)) + i).getFlags(); // copy over flags from org to title ccList.get(ccListSize - numOrgTitlePairs + i).setFlags(orgFlags); } } return ccList.toArray(new ContactChange[ccList.size()]); } public static ContactChange[] randomContactUpdate(ContactChange[] contact) { final int originalDetailsNum = contact.length; final long internalCntId = contact[0].getInternalContactId(); final long backendCntId = contact[0].getBackendContactId(); final long nabCntId = contact[0].getNabContactId(); int numDeletedDetails = 0, curNumDeletedDetails = 0, numAddedDetails = 0, curNumAddedDetails = 0, numChangedDetails = 0, curNumChangedDetails = 0; // At best we can only delete all but one detail numDeletedDetails = randomPositiveInt(originalDetailsNum - 1); // At best we can only change all details minus the ones we will delete numChangedDetails = randomPositiveInt(originalDetailsNum - numDeletedDetails); // Reasonable maximum of details we can add numAddedDetails = randomPositiveInt(MAX_NUM_DETAILS_ADD); final int updateCcListSize = numAddedDetails + numChangedDetails + numDeletedDetails; ContactChange[] updateCcList = new ContactChange[updateCcListSize]; for(int i = 0; i < updateCcListSize; i++) { if(curNumChangedDetails < numChangedDetails) { updateCcList[i] = generateUpdateDetailChange(contact[i]); curNumChangedDetails++; continue; } if (curNumDeletedDetails < numDeletedDetails) { updateCcList[i] = generateDeleteDetailChange(contact[i]); curNumDeletedDetails++; continue; } if(curNumAddedDetails < numAddedDetails) { int key; do { // get a random key and don't let it be a unique key to simplify things key = randomKey(); if(isKeyPlatformSupported(key)) { if(!isUniqueKeyForContact(key) || (isUniqueKeyForContact(key) && !isKeyPresent(key, updateCcList) && !isKeyPresent(key, contact))) { break; } } } while(true); // The new detail, preferred flag not allowed to simplify things a little final ContactChange addDetailCc = randomContactChange(key, internalCntId, backendCntId, nabCntId, false); //addDetailCc.setInternalDetailId(randomPositiveLong()); addDetailCc.setType(ContactChange.TYPE_ADD_DETAIL); updateCcList[i] = addDetailCc; curNumAddedDetails++; } } return updateCcList; } public static ContactChange[] generatedUpdatedContact(ContactChange[] contact, ContactChange[] update) { if(update == null || update.length == 0) { return contact; } final List<ContactChange> updatedContact = new ArrayList<ContactChange>(); final int contactSize = contact.length; final int updateSize = update.length; for(int i = 0; i < contactSize; i++) { ContactChange cc = contact[i]; int updateType = ContactChange.TYPE_UNKNOWN; if(updateSize > i) { updateType = update[i].getType(); } if(updateType == ContactChange.TYPE_UPDATE_DETAIL) { cc = update[i]; } else if(updateType == ContactChange.TYPE_DELETE_DETAIL) { continue; } updatedContact.add(cc); } for(int i = 0; i < updateSize; i++) { final ContactChange cc = update[i]; //final int key = cc.getKey(); if(cc.getType() == ContactChange.TYPE_ADD_DETAIL) { //updatedContact.add(lastIndexForKeyInCcList(key, updatedContact) + 1, cc); // Since we are using areUnsortedChangeListsEqual to compare we can just add instead of above updatedContact.add(cc); } } return updatedContact.toArray(new ContactChange[updatedContact.size()]); } /** * Finds the last index for the specified key. * This method uses recursion. */ private static int lastIndexForKeyInCcList(int key, List<ContactChange> ccList) { if(ccList == null || ccList.size() == 0) { return -1; } final int listSize = ccList.size(); for(int i = listSize - 1; i > -1; i--) { if(ccList.get(i).getKey() == key) { return i; } } // Yes, this is recursion... switch(key) { case ContactChange.KEY_VCARD_TITLE: return lastIndexForKeyInCcList(ContactChange.KEY_VCARD_ORG, ccList); case ContactChange.KEY_VCARD_ORG: return lastIndexForKeyInCcList(ContactChange.KEY_VCARD_ADDRESS, ccList); case ContactChange.KEY_VCARD_ADDRESS: return lastIndexForKeyInCcList(ContactChange.KEY_VCARD_EMAIL, ccList); case ContactChange.KEY_VCARD_EMAIL: return lastIndexForKeyInCcList(ContactChange.KEY_VCARD_PHONE, ccList); case ContactChange.KEY_VCARD_PHONE: return lastIndexForKeyInCcList(ContactChange.KEY_VCARD_NICKNAME, ccList); case ContactChange.KEY_VCARD_NICKNAME: return lastIndexForKeyInCcList(ContactChange.KEY_VCARD_NOTE, ccList); case ContactChange.KEY_VCARD_NOTE: return lastIndexForKeyInCcList(ContactChange.KEY_VCARD_NAME, ccList); } return -1; } public static boolean isKeyPresent(int key, ContactChange[] ccList) { if(ccList == null || ccList.length == 0) { return false; } final int listSize = ccList.length; for(int i = listSize - 1; i > -1; i--) { if(ccList[i] != null && ccList[i].getKey() == key) { return true; } } return false; } private static boolean isKeyPlatformSupported(int key) { switch (key) { case ContactChange.KEY_VCARD_TITLE: case ContactChange.KEY_VCARD_ORG: case ContactChange.KEY_VCARD_ADDRESS: case ContactChange.KEY_VCARD_EMAIL: case ContactChange.KEY_VCARD_PHONE: case ContactChange.KEY_VCARD_NOTE: case ContactChange.KEY_VCARD_NAME: return true; case ContactChange.KEY_VCARD_URL: case ContactChange.KEY_VCARD_NICKNAME: return VersionUtils.is2XPlatform(); } return false; } private static ContactChange generateUpdateDetailChange(ContactChange cc) { if(cc == null) { return null; } final int key = cc.getKey(); boolean changed = false; String value = cc.getValue(); int flags = cc.getFlags(); int newFlags = flags; if(randomTrue()) { value = randomValue(key); changed = true; } if(randomTrue()) { flags = randomFlags(key, false); if(newFlags != flags) { changed = true; } } if(!changed) { value = randomValue(key); } final ContactChange updateDetailCc = new ContactChange(key, value, newFlags); updateDetailCc.setType(ContactChange.TYPE_UPDATE_DETAIL); updateDetailCc.setInternalContactId(cc.getInternalContactId()); updateDetailCc.setInternalDetailId(cc.getInternalDetailId()); updateDetailCc.setBackendContactId(cc.getBackendContactId()); updateDetailCc.setBackendDetailId(cc.getBackendDetailId()); updateDetailCc.setNabContactId(cc.getNabContactId()); updateDetailCc.setNabDetailId(cc.getNabDetailId()); return updateDetailCc; } private static ContactChange generateDeleteDetailChange(ContactChange cc) { if(cc == null) { return null; } final ContactChange deleteDetailCc = new ContactChange(); deleteDetailCc.setKey(cc.getKey()); deleteDetailCc.setType(ContactChange.TYPE_DELETE_DETAIL); deleteDetailCc.setInternalContactId(cc.getInternalContactId()); deleteDetailCc.setInternalDetailId(cc.getInternalDetailId()); deleteDetailCc.setBackendContactId(cc.getBackendContactId()); deleteDetailCc.setBackendDetailId(cc.getBackendDetailId()); deleteDetailCc.setNabContactId(cc.getNabContactId()); deleteDetailCc.setNabDetailId(cc.getNabDetailId()); return deleteDetailCc; } private static void generateRandomChangesForKey( List<ContactChange> ccList, int key, long internalContactId, long backendContactId, long nabContactId, int numChanges) { boolean preferredSelected = false; for(int i = 0; i < numChanges; i++) { ContactChange cc = randomContactChange(key, internalContactId, backendContactId, nabContactId, !preferredSelected); if(!preferredSelected) { preferredSelected = (cc.getFlags() & ContactChange.FLAG_PREFERRED) == ContactChange.FLAG_PREFERRED; } ccList.add(cc); } } private static ContactChange randomContactChange(int key, long internalContactId, long backendContactId, long nabContactId, boolean allowPreferred) { ContactChange cc = randomContactChange(key, allowPreferred); cc.setInternalContactId(internalContactId); cc.setBackendContactId(backendContactId); cc.setNabContactId(nabContactId); return cc; } private static ContactChange randomContactChange(int key, boolean allowPreferred) { return new ContactChange(key, randomValue(key), randomFlags(key, allowPreferred)); } private static int randomKey() { return sKeyArray[randomPositiveInt(sKeyArray.length - 1)]; } private static Name randomName() { String firstname = null, surname = null, midname = null, suffix = null, title = null; if(randomTrue()) { firstname = randomString(); } if(randomTrue()) { surname = randomString(); } if(randomTrue()) { midname = randomString(); } if(randomTrue()) { if(randomTrue()) { title = randomString(); } else { title = mNameTitleList[randomPositiveInt(mNameTitleList.length)]; } } if(randomTrue()) { suffix = randomString(); } if(randomTrue()) { firstname = randomString(); } Name name = new Name(); if(firstname == null && surname == null) { /* So that we have one part not null! * Note that we ignored middle name, suffix and title in the above check * The reason for doing so is that 2.X NAB cannot work with just middle name, prefix and suffix fields! */ firstname = randomString(); } name.firstname = firstname; name.midname = midname; name.surname = surname; name.title = title; name.suffixes = suffix; return name; } private static PostalAddress randomAddress() { String addressLine1 = null, addressLine2 = null, city = null, county = null, pobox = null, postcode = null, country = null; if(randomTrue()) { pobox = randomString(); } if(randomTrue()) { addressLine1 = randomString(); } if(randomTrue()) { addressLine2 = randomString(); } if(randomTrue()) { city = randomString(); } if(randomTrue()) { county = randomString(); } if(randomTrue()) { postcode = randomNumbersString(); } if(randomTrue()) { country = randomString(); } PostalAddress address = new PostalAddress(); if( pobox != null || addressLine1 != null || addressLine2 != null || city != null || county != null || postcode != null || country != null) { address.addressLine1 = addressLine1; address.addressLine2 = addressLine2; address.postOfficeBox = pobox; address.postCode = postcode; address.city = city; address.county = county; address.country = country; } else { // So that we have one part not null address.addressLine1 = randomString(); } return address; } private static Organisation randomOrganization() { String company = null, department = null; if(randomTrue()) { company = randomString(); } if(randomTrue()) { // Department only matters in 2.X department = randomString(); } Organisation org = new Organisation(); if(company == null && department == null || (!VersionUtils.is2XPlatform() && company == null)) { // So that we have one part not null // Also in 1.X we should have a company because department doesn't matter company = randomString(); } org.name = company; org.unitNames.add(department); return org; } private static String randomValue(int key) { switch (key) { case ContactChange.KEY_VCARD_NAME: return VCardHelper.makeName(randomName()); case ContactChange.KEY_VCARD_PHONE: return randomPhoneNumber(); case ContactChange.KEY_VCARD_EMAIL: return randomEmail(); case ContactChange.KEY_VCARD_ADDRESS: return VCardHelper.makePostalAddress(randomAddress()); case ContactChange.KEY_VCARD_ORG: return VCardHelper.makeOrg(randomOrganization()); case ContactChange.KEY_VCARD_DATE: return randomBirthday(); // Only birthday supported currently } return randomString(); } // private static String randomUpdatedValue(ContactChange cc) { // final int key = cc.getKey(); // switch(key) { // case ContactChange.KEY_VCARD_NAME: // // get old value first // final Name name = VCardHelper.getName(cc.getValue()); // final Name randomName = randomName(); // if(!TextUtils.isEmpty(randomName.firstname)) { // name.firstname = randomName.firstname; // } // // if(!TextUtils.isEmpty(randomName.midname)) { // name.firstname = randomName.midname; // } // // if(!TextUtils.isEmpty(randomName.surname)) { // name.firstname = randomName.surname; // } // // if(!TextUtils.isEmpty(randomName.title)) { // name.firstname = randomName.title; // } // // if(!TextUtils.isEmpty(randomName.suffixes)) { // name.firstname = randomName.suffixes; // } // // return VCardHelper.makeName(name); // case ContactChange.KEY_VCARD_ADDRESS: // final PostalAddress address = VCardHelper.getPostalAddress(cc.getValue()); // final PostalAddress randomAddress = // break; // case ContactChange.KEY_VCARD_ORG: // break; // // } // // return randomValue(key); // } private static int randomPhoneFlags() { if(randomTrue()) { return ContactChange.FLAG_CELL; } if(randomTrue()) { return ContactChange.FLAG_HOME; } if(randomTrue()) { return ContactChange.FLAG_WORK; } if(VersionUtils.is2XPlatform() && randomTrue()) { return ContactChange.FLAGS_WORK_CELL; } if(VersionUtils.is2XPlatform() && randomTrue()) { return ContactChange.FLAG_FAX; } if(randomTrue()) { return ContactChange.FLAGS_WORK_FAX; } if(randomTrue()) { return ContactChange.FLAGS_HOME_FAX; } return ContactChange.FLAG_NONE; } private static int randomBasicFlags() { if(randomTrue()) { return ContactChange.FLAG_HOME; } if(randomTrue()) { return ContactChange.FLAG_WORK; } return ContactChange.FLAG_NONE; } private static int randomFlags(int key, boolean allowPreferred) { int flags = ContactChange.FLAG_NONE; switch(key) { case ContactChange.KEY_VCARD_PHONE: flags = randomPhoneFlags(); break; case ContactChange.KEY_VCARD_URL: case ContactChange.KEY_VCARD_ADDRESS: case ContactChange.KEY_VCARD_EMAIL: flags = randomBasicFlags(); break; case ContactChange.KEY_VCARD_TITLE: case ContactChange.KEY_VCARD_ORG: if(randomTrue()) { flags = ContactChange.FLAG_WORK; } break; case ContactChange.KEY_VCARD_DATE: // Only birthday currently supported flags = ContactChange.FLAG_BIRTHDAY; // fall through default: allowPreferred = false; break; } if(allowPreferred && randomTrue()) { flags|= ContactChange.FLAG_PREFERRED; } return flags; } /** * Returns provided value if the probability Threshold given is met * Otherwise returns zero * @param treshold * @param value * @return value or zero */ private static int valueForLikelihoodPercentage(int percentage, int value) { return randomPositiveInt(100) < percentage ? value : 0; } private static int randomPositiveInt(int limit) { return Math.abs(sRn.nextInt() % limit); } private static long randomPositiveLong() { return Math.abs(sRn.nextLong()); } private static int rand(int lo, int hi) { int n = hi - lo + 1; int i = sRn.nextInt() % n; if (i < 0) i = -i; return lo + i; } private static String randomString(int lo, int hi, char loChar, char hiChar) { int n = rand(lo, hi); byte b[] = new byte[n]; for (int i = 0; i < n; i++) b[i] = (byte)rand(loChar, hiChar); return new String(b, 0); } private static String randomString() { return randomString(4, 20, 'a', 'z'); } private static String randomPhoneNumber() { return "+"+randomString(4, 12, '0', '9'); } private static String randomNumbersString() { return randomString(4, 12, '0', '9'); } private static String randomEmail() { return randomString(4, 15, 'a', 'z')+"@"+randomString(4, 10, 'a', 'z')+".com"; } private static Calendar randomDate() { Date date = new Date(sRn.nextLong()); Calendar calendar = Calendar.getInstance(); calendar.setTime(date); return calendar; } private static String randomBirthday() { final Calendar calendar = Calendar.getInstance(); Calendar randomDate = null; do { randomDate = randomDate(); final int currentYear = calendar.get(Calendar.YEAR); final int birthdayYear = currentYear - randomPositiveInt(100); // Maximum 100 years old randomDate.set(Calendar.YEAR, birthdayYear); } while(calendar.compareTo(randomDate) >= 0); final StringBuilder sb = new StringBuilder(); sb.append(randomDate.get(Calendar.DAY_OF_MONTH)); sb.append('-'); sb.append((randomDate.get(Calendar.MONTH)+1)); sb.append('-'); sb.append(randomDate.get(Calendar.YEAR)); return sb.toString(); } private static boolean randomTrue() { return sRn.nextBoolean(); } }