21
21
* along with this program. If not, see <http://www.gnu.org/licenses/>.
24
package org.waxworlds.edam.importcontacts;
24
package am.ed.importcontacts;
26
26
import java.util.HashMap;
27
27
import java.util.HashSet;
29
import org.waxworlds.edam.importcontacts.Importer.AbortImportException;
31
import android.app.Activity;
32
import android.database.Cursor;
33
import android.provider.Contacts;
36
29
public class ContactsCache
38
private HashMap< String, Long > _contacts;
40
private HashMap< Long, HashSet< String > > _contactNumbers;
41
private HashMap< Long, HashSet< String > > _contactEmails;
42
private HashMap< Long, HashSet< String > > _contactAddresses;
44
public boolean exists( String name )
46
return _contacts.containsKey( name );
49
public Long getId( String name )
51
return _contacts.get( name );
54
public void remove( String name )
56
_contacts.remove( name );
59
public void put( Long id, String name )
61
_contacts.put( name, id );
64
public boolean hasNumber( Long id, String number )
66
HashSet< String > cache = _contactNumbers.get( id );
67
return cache != null && cache.contains( number );
70
public void addNumber( Long id, String number )
72
HashSet< String > cache = _contactNumbers.get( id );
74
cache = new HashSet< String >();
75
_contactNumbers.put( id, cache );
80
public boolean hasEmail( Long id, String email )
82
HashSet< String > cache = _contactEmails.get( id );
83
return cache != null && cache.contains( email );
86
public void addEmail( Long id, String email )
88
HashSet< String > cache = _contactEmails.get( id );
90
cache = new HashSet< String >();
91
_contactEmails.put( id, cache );
96
public boolean hasAddress( Long id, String address )
98
HashSet< String > cache = _contactAddresses.get( id );
99
return cache != null && cache.contains( address );
102
public void addAddress( Long id, String address )
104
HashSet< String > cache = _contactAddresses.get( id );
105
if( cache == null ) {
106
cache = new HashSet< String >();
107
_contactAddresses.put( id, cache );
109
cache.add( address );
112
public void buildCache( Activity activity )
113
throws AbortImportException
118
// init contacts caches
119
_contacts = new HashMap< String, Long >();
120
_contactNumbers = new HashMap< Long, HashSet< String > >();
121
_contactEmails = new HashMap< Long, HashSet< String > >();
122
_contactAddresses = new HashMap< Long, HashSet< String > >();
124
// query and store map of contact names to ids
125
cols = new String[] { Contacts.People._ID, Contacts.People.NAME };
126
cur = activity.managedQuery( Contacts.People.CONTENT_URI,
127
cols, null, null, null);
128
if( cur.moveToFirst() ) {
129
int idCol = cur.getColumnIndex( Contacts.People._ID );
130
int nameCol = cur.getColumnIndex( Contacts.People.NAME );
132
_contacts.put( cur.getString( nameCol ), cur.getLong( idCol ) );
133
} while( cur.moveToNext() );
136
// query and store map of contact ids to sets of phone numbers
137
cols = new String[] { Contacts.Phones.PERSON_ID,
138
Contacts.Phones.NUMBER };
139
cur = activity.managedQuery( Contacts.Phones.CONTENT_URI,
140
cols, null, null, null);
141
if( cur.moveToFirst() ) {
142
int personIdCol = cur.getColumnIndex( Contacts.Phones.PERSON_ID );
143
int numberCol = cur.getColumnIndex( Contacts.Phones.NUMBER );
145
Long id = cur.getLong( personIdCol );
146
String number = Importer.sanitisePhoneNumber(
147
cur.getString( numberCol ) );
148
if( number != null ) {
149
HashSet< String > numbers = _contactNumbers.get( id );
150
if( numbers == null ) {
151
numbers = new HashSet< String >();
152
_contactNumbers.put( id, numbers );
154
numbers.add( number );
156
} while( cur.moveToNext() );
159
// query and store map of contact ids to sets of email addresses
160
cols = new String[] { Contacts.ContactMethods.PERSON_ID,
161
Contacts.ContactMethods.DATA };
162
cur = activity.managedQuery( Contacts.ContactMethods.CONTENT_URI,
163
cols, Contacts.ContactMethods.KIND + " = ?",
164
new String[] { "" + Contacts.KIND_EMAIL }, null );
165
if( cur.moveToFirst() ) {
166
int personIdCol = cur.getColumnIndex(
167
Contacts.ContactMethods.PERSON_ID );
168
int addressCol = cur.getColumnIndex(
169
Contacts.ContactMethods.DATA );
171
Long id = cur.getLong( personIdCol );
172
String address = Importer.sanitiseEmailAddress(
173
cur.getString( addressCol ) );
174
if( address != null ) {
175
HashSet< String > addresses = _contactEmails.get( id );
176
if( addresses == null ) {
177
addresses = new HashSet< String >();
178
_contactEmails.put( id, addresses );
180
addresses.add( address );
182
} while( cur.moveToNext() );
185
// query and store map of contact ids to sets of postal addresses
186
cols = new String[] { Contacts.ContactMethods.PERSON_ID,
187
Contacts.ContactMethods.DATA };
188
cur = activity.managedQuery( Contacts.ContactMethods.CONTENT_URI,
189
cols, Contacts.ContactMethods.KIND + " = ?",
190
new String[] { "" + Contacts.KIND_POSTAL }, null );
191
if( cur.moveToFirst() ) {
192
int personIdCol = cur.getColumnIndex(
193
Contacts.ContactMethods.PERSON_ID );
194
int addressCol = cur.getColumnIndex(
195
Contacts.ContactMethods.DATA );
197
Long id = cur.getLong( personIdCol );
198
String address = cur.getString( addressCol );
199
if( address != null ) {
200
HashSet< String > addresses = _contactAddresses.get( id );
201
if( addresses == null ) {
202
addresses = new HashSet< String >();
203
_contactAddresses.put( id, addresses );
205
addresses.add( address );
207
} while( cur.moveToNext() );
32
* Information that can be used to identify a contact within the cache
34
static public class CacheIdentifier
37
NONE, NAME, ORGANISATION, PRIMARY_NUMBER, PRIMARY_EMAIL }
40
private String _detail;
42
protected CacheIdentifier()
47
protected CacheIdentifier( Type type, String detail )
58
public String getDetail()
64
// mappings of contact names, organisations and primary numbers to ids
65
private HashMap< String, Long > _contactsByName
66
= new HashMap< String, Long >();
67
private HashMap< String, Long > _contactsByOrg
68
= new HashMap< String, Long >();
69
private HashMap< String, Long > _contactsByNumber
70
= new HashMap< String, Long >();
71
private HashMap< String, Long > _contactsByEmail
72
= new HashMap< String, Long >();
74
// mapping of contact ids to sets of associated data
75
private HashMap< Long, HashSet< String > > _contactNumbers
76
= new HashMap< Long, HashSet< String > >();
77
private HashMap< Long, HashSet< String > > _contactEmails
78
= new HashMap< Long, HashSet< String > >();
79
private HashMap< Long, HashSet< String > > _contactAddresses
80
= new HashMap< Long, HashSet< String > >();
81
private HashMap< Long, HashSet< String > > _contactOrganisations
82
= new HashMap< Long, HashSet< String > >();
84
public static CacheIdentifier createIdentifier(
85
Importer.ContactData contact )
87
if( contact.hasName() ) {
88
String name = normaliseName( contact.getName() );
90
return new CacheIdentifier(
91
CacheIdentifier.Type.NAME, name );
94
if( contact.hasPrimaryOrganisation() ) {
95
String organisation = normaliseOrganisation(
96
contact.getPrimaryOrganisation() );
97
if( organisation != null )
98
return new CacheIdentifier(
99
CacheIdentifier.Type.ORGANISATION, organisation );
102
if( contact.hasPrimaryNumber() ) {
103
String number = normalisePhoneNumber( contact.getPrimaryNumber() );
105
return new CacheIdentifier(
106
CacheIdentifier.Type.PRIMARY_NUMBER, number );
109
if( contact.hasPrimaryEmail() ) {
110
String email = normaliseEmailAddress( contact.getPrimaryEmail() );
112
return new CacheIdentifier(
113
CacheIdentifier.Type.PRIMARY_EMAIL, email );
119
public boolean canLookup( CacheIdentifier identifier )
121
return lookup( identifier ) != null;
124
public Long lookup( CacheIdentifier identifier )
126
switch( identifier.getType() )
129
return _contactsByName.get( identifier.getDetail() );
131
return _contactsByOrg.get( identifier.getDetail() );
133
return _contactsByNumber.get( identifier.getDetail() );
135
return _contactsByEmail.get( identifier.getDetail() );
140
public Long removeLookup( CacheIdentifier identifier )
142
switch( identifier.getType() )
145
return _contactsByName.remove( identifier.getDetail() );
147
return _contactsByOrg.remove( identifier.getDetail() );
149
return _contactsByNumber.remove( identifier.getDetail() );
151
return _contactsByEmail.remove( identifier.getDetail() );
156
public void addLookup( CacheIdentifier identifier, Long id )
158
switch( identifier.getType() )
161
_contactsByName.put( identifier.getDetail(), id );
164
_contactsByOrg.put( identifier.getDetail(), id );
167
_contactsByNumber.put( identifier.getDetail(), id );
170
_contactsByEmail.put( identifier.getDetail(), id );
175
public void removeAssociatedData( Long id )
177
_contactNumbers.remove( id );
178
_contactEmails.remove( id );
179
_contactAddresses.remove( id );
180
_contactOrganisations.remove( id );
183
public boolean hasAssociatedNumber( Long id, String number )
185
number = normalisePhoneNumber( number );
186
if( number == null ) return false;
188
HashSet< String > set = _contactNumbers.get( id );
189
return set != null && set.contains( number );
192
public void addAssociatedNumber( Long id, String number )
194
number = normalisePhoneNumber( number );
195
if( number == null ) return;
197
HashSet< String > set = _contactNumbers.get( id );
199
set = new HashSet< String >();
200
_contactNumbers.put( id, set );
202
set.add( normalisePhoneNumber( number ) );
205
public boolean hasAssociatedEmail( Long id, String email )
207
email = normaliseEmailAddress( email );
208
if( email == null ) return false;
210
HashSet< String > set = _contactEmails.get( id );
211
return set != null && set.contains( normaliseEmailAddress( email ) );
214
public void addAssociatedEmail( Long id, String email )
216
email = normaliseEmailAddress( email );
217
if( email == null ) return;
219
HashSet< String > set = _contactEmails.get( id );
221
set = new HashSet< String >();
222
_contactEmails.put( id, set );
224
set.add( normaliseEmailAddress( email ) );
227
public boolean hasAssociatedAddress( Long id, String address )
229
address = normaliseAddress( address );
230
if( address == null ) return false;
232
HashSet< String > set = _contactAddresses.get( id );
233
return set != null && set.contains( normaliseAddress( address ) );
236
public void addAssociatedAddress( Long id, String address )
238
address = normaliseAddress( address );
239
if( address == null ) return;
241
HashSet< String > set = _contactAddresses.get( id );
243
set = new HashSet< String >();
244
_contactAddresses.put( id, set );
246
set.add( normaliseAddress( address ) );
249
public boolean hasAssociatedOrganisation( Long id, String organisation )
251
organisation = normaliseOrganisation( organisation );
252
if( organisation == null ) return false;
254
HashSet< String > set = _contactOrganisations.get( id );
255
return set != null && set.contains(
256
normaliseOrganisation( organisation ) );
259
public void addAssociatedOrganisation( Long id, String organisation )
261
organisation = normaliseOrganisation( organisation );
262
if( organisation == null ) return;
264
HashSet< String > set = _contactOrganisations.get( id );
266
set = new HashSet< String >();
267
_contactOrganisations.put( id, set );
269
set.add( normaliseOrganisation( organisation ) );
272
static public String normaliseName( String name )
274
if( name == null ) return null;
276
return name.length() > 0? name : null;
279
static public String normalisePhoneNumber( String number )
281
if( number == null ) return null;
282
number = number.trim().replaceAll( "[-\\(\\) ]", "" );
283
return number.length() > 0? number : null;
286
static public String normaliseEmailAddress( String email )
288
if( email == null ) return null;
289
email = email.trim().toLowerCase();
290
return email.length() > 0? email : null;
293
static public String normaliseOrganisation( String organisation )
295
if( organisation == null ) return null;
296
organisation = organisation.trim();
297
return organisation.length() > 0? organisation : null;
300
static public String normaliseAddress( String address )
302
if( address == null ) return null;
303
address = address.trim();
304
return address.length() > 0? address : null;