/android/import-contacts

To get this branch, use:
bzr branch http://bzr.ed.am/android/import-contacts

« back to all changes in this revision

Viewing changes to src/am/ed/importcontacts/ContactsCache.java

  • Committer: edam
  • Date: 2009-01-13 06:35:26 UTC
  • Revision ID: edam@waxworlds.org-20090113063526-l9t1s9git4bav60a
- new contact's phone numebrs and email addresses are added to the caches after those contacts are updated to account for the situation where the same contact is imported again from another file (or the contact exists twice in the same file!?)

Show diffs side-by-side

added added

removed removed

1
 
/*
2
 
 * ContactsCache.java
3
 
 *
4
 
 * Copyright (C) 2011 to 2013 Tim Marston <tim@ed.am>
5
 
 *
6
 
 * This file is part of the Import Contacts program (hereafter referred
7
 
 * to as "this program").  For more information, see
8
 
 * http://ed.am/dev/android/import-contacts
9
 
 *
10
 
 * This program is free software: you can redistribute it and/or modify
11
 
 * it under the terms of the GNU General Public License as published by
12
 
 * the Free Software Foundation, either version 3 of the License, or
13
 
 * (at your option) any later version.
14
 
 *
15
 
 * This program is distributed in the hope that it will be useful,
16
 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17
 
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
 
 * GNU General Public License for more details.
19
 
 *
20
 
 * You should have received a copy of the GNU General Public License
21
 
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
 
 */
23
 
 
24
 
package am.ed.importcontacts;
25
 
 
26
 
import java.util.HashMap;
27
 
import java.util.HashSet;
28
 
import java.util.Locale;
29
 
 
30
 
public class ContactsCache
31
 
{
32
 
        /**
33
 
         * A thing that can be used to identify (or lookup) a contact within the
34
 
         * contacts cache.  It is not a reference to a cache entry and may not
35
 
         * identify an existing contact in the cache.
36
 
         */
37
 
        public static class CacheIdentifier
38
 
        {
39
 
                public enum Type { NAME, ORGANISATION, PRIMARY_NUMBER, PRIMARY_EMAIL }
40
 
 
41
 
                private Type _type;
42
 
                private String _detail;
43
 
 
44
 
                /**
45
 
                 * Obtain a cache identifier.  This routine is designed to be as robust
46
 
                 * as possible (in terms of bad or null detail values), and to return
47
 
                 * null when a cache identifier can not be created.
48
 
                 *
49
 
                 * @param type the detail type
50
 
                 * @param detail the detail
51
 
                 * @return the cache identifier, or null
52
 
                 */
53
 
                public static CacheIdentifier factory( Type type, String detail )
54
 
                {
55
 
                        switch( type )
56
 
                        {
57
 
                        case NAME: detail = normaliseName( detail ); break;
58
 
                        case ORGANISATION: detail = normaliseOrganisation( detail ); break;
59
 
                        case PRIMARY_NUMBER: detail = normalisePhoneNumber( detail ); break;
60
 
                        case PRIMARY_EMAIL: detail = normaliseEmailAddress( detail ); break;
61
 
                        default: return null;
62
 
                        }
63
 
                        if( detail == null ) return null;
64
 
                        return new CacheIdentifier( type, detail );
65
 
                }
66
 
 
67
 
                /**
68
 
                 * Obtain a cache identifier from contact data.  This routine is
69
 
                 * designed to be as robust as possible and may return null when a cache
70
 
                 * identifier can not be created.
71
 
                 *
72
 
                 * @param contact the contact data
73
 
                 * @return the cache identifier, or null
74
 
                 */
75
 
                public static CacheIdentifier factory( Importer.ContactData contact )
76
 
                {
77
 
                        CacheIdentifier identifier = null;
78
 
 
79
 
                        if( contact.hasName() )
80
 
                                identifier = factory( CacheIdentifier.Type.NAME,
81
 
                                        contact.getName() );
82
 
                        if( identifier != null ) return identifier;
83
 
 
84
 
                        if( contact.hasPrimaryOrganisation() )
85
 
                                identifier = factory( CacheIdentifier.Type.ORGANISATION,
86
 
                                        contact.getPrimaryOrganisation() );
87
 
                        if( identifier != null ) return identifier;
88
 
 
89
 
                        if( contact.hasPrimaryNumber() )
90
 
                                identifier = factory( CacheIdentifier.Type.PRIMARY_NUMBER,
91
 
                                        contact.getPrimaryNumber() );
92
 
                        if( identifier != null ) return identifier;
93
 
 
94
 
                        if( contact.hasPrimaryEmail() )
95
 
                                identifier = factory( CacheIdentifier.Type.PRIMARY_EMAIL,
96
 
                                        contact.getPrimaryEmail() );
97
 
                        if( identifier != null ) return identifier;
98
 
 
99
 
                        return null;
100
 
                }
101
 
 
102
 
                protected CacheIdentifier( Type type, String detail )
103
 
                {
104
 
                        _type = type;
105
 
                        _detail = detail;
106
 
                }
107
 
 
108
 
                public Type getType()
109
 
                {
110
 
                        return _type;
111
 
                }
112
 
 
113
 
                public String getDetail()
114
 
                {
115
 
                        return _detail;
116
 
                }
117
 
        }
118
 
 
119
 
        // mappings of contact names, organisations and primary numbers to ids
120
 
        private HashMap< String, Long > _contactsByName
121
 
                = new HashMap< String, Long >();
122
 
        private HashMap< String, Long > _contactsByOrg
123
 
                = new HashMap< String, Long >();
124
 
        private HashMap< String, Long > _contactsByNumber
125
 
                = new HashMap< String, Long >();
126
 
        private HashMap< String, Long > _contactsByEmail
127
 
                = new HashMap< String, Long >();
128
 
 
129
 
        // mapping of contact ids to sets of associated data
130
 
        private HashMap< Long, HashSet< String > > _contactNumbers
131
 
                = new HashMap< Long, HashSet< String > >();
132
 
        private HashMap< Long, HashSet< String > > _contactEmails
133
 
                = new HashMap< Long, HashSet< String > >();
134
 
        private HashMap< Long, HashSet< String > > _contactAddresses
135
 
                = new HashMap< Long, HashSet< String > >();
136
 
        private HashMap< Long, HashSet< String > > _contactOrganisations
137
 
                = new HashMap< Long, HashSet< String > >();
138
 
        private HashMap< Long, HashSet< String > > _contactNotes
139
 
                = new HashMap< Long, HashSet< String > >();
140
 
        private HashMap< Long, String > _contactBirthdays
141
 
                = new HashMap< Long, String >();
142
 
 
143
 
        public boolean canLookup( CacheIdentifier identifier )
144
 
        {
145
 
                return lookup( identifier ) != null;
146
 
        }
147
 
 
148
 
        /**
149
 
         * Retrieve the contact id of a contact identified by the specified cache
150
 
         * identifier, if it exists.
151
 
         *
152
 
         * @param identifier the cache identifier
153
 
         * @return a contact id, or null
154
 
         */
155
 
        public Long lookup( CacheIdentifier identifier )
156
 
        {
157
 
                switch( identifier.getType() )
158
 
                {
159
 
                case NAME:
160
 
                        return _contactsByName.get( identifier.getDetail() );
161
 
                case ORGANISATION:
162
 
                        return _contactsByOrg.get( identifier.getDetail() );
163
 
                case PRIMARY_NUMBER:
164
 
                        return _contactsByNumber.get( identifier.getDetail() );
165
 
                case PRIMARY_EMAIL:
166
 
                        return _contactsByEmail.get( identifier.getDetail() );
167
 
                }
168
 
                return null;
169
 
        }
170
 
 
171
 
        /**
172
 
         * Remove any cache entry that is identified by the cache identifier.
173
 
         *
174
 
         * @param identifier the cache identifier
175
 
         * @return the contact id of the contact that was removed, or null
176
 
         */
177
 
        public Long removeLookup( CacheIdentifier identifier )
178
 
        {
179
 
                switch( identifier.getType() )
180
 
                {
181
 
                case NAME:
182
 
                        return _contactsByName.remove( identifier.getDetail() );
183
 
                case ORGANISATION:
184
 
                        return _contactsByOrg.remove( identifier.getDetail() );
185
 
                case PRIMARY_NUMBER:
186
 
                        return _contactsByNumber.remove( identifier.getDetail() );
187
 
                case PRIMARY_EMAIL:
188
 
                        return _contactsByEmail.remove( identifier.getDetail() );
189
 
                }
190
 
                return null;
191
 
        }
192
 
 
193
 
        /**
194
 
         * Add a lookup from a contact identifier to a contact id to the cache.
195
 
         *
196
 
         * @param identifier the cache identifier
197
 
         * @param id teh contact id
198
 
         */
199
 
        public void addLookup( CacheIdentifier identifier, Long id )
200
 
        {
201
 
                switch( identifier.getType() )
202
 
                {
203
 
                case NAME:
204
 
                        _contactsByName.put( identifier.getDetail(), id );
205
 
                        break;
206
 
                case ORGANISATION:
207
 
                        _contactsByOrg.put( identifier.getDetail(), id );
208
 
                        break;
209
 
                case PRIMARY_NUMBER:
210
 
                        _contactsByNumber.put( identifier.getDetail(), id );
211
 
                        break;
212
 
                case PRIMARY_EMAIL:
213
 
                        _contactsByEmail.put( identifier.getDetail(), id );
214
 
                        break;
215
 
                }
216
 
        }
217
 
 
218
 
        /**
219
 
         * Remove any data that is associated with an contact id.
220
 
         *
221
 
         * @param id
222
 
         */
223
 
        public void removeAssociatedData( Long id )
224
 
        {
225
 
                _contactNumbers.remove( id );
226
 
                _contactEmails.remove( id );
227
 
                _contactAddresses.remove( id );
228
 
                _contactOrganisations.remove( id );
229
 
                _contactNotes.remove( id );
230
 
        }
231
 
 
232
 
        public boolean hasAssociatedNumber( Long id, String number )
233
 
        {
234
 
                number = normalisePhoneNumber( number );
235
 
                if( number == null ) return false;
236
 
 
237
 
                HashSet< String > set = _contactNumbers.get( id );
238
 
                return set != null && set.contains( number );
239
 
        }
240
 
 
241
 
        public void addAssociatedNumber( Long id, String number )
242
 
        {
243
 
                number = normalisePhoneNumber( number );
244
 
                if( number == null ) return;
245
 
 
246
 
                HashSet< String > set = _contactNumbers.get( id );
247
 
                if( set == null ) {
248
 
                        set = new HashSet< String >();
249
 
                        _contactNumbers.put( id, set );
250
 
                }
251
 
                set.add( number );
252
 
        }
253
 
 
254
 
        public boolean hasAssociatedEmail( Long id, String email )
255
 
        {
256
 
                email = normaliseEmailAddress( email );
257
 
                if( email == null ) return false;
258
 
 
259
 
                HashSet< String > set = _contactEmails.get( id );
260
 
                return set != null && set.contains( email );
261
 
        }
262
 
 
263
 
        public void addAssociatedEmail( Long id, String email )
264
 
        {
265
 
                email = normaliseEmailAddress( email );
266
 
                if( email == null ) return;
267
 
 
268
 
                HashSet< String > set = _contactEmails.get( id );
269
 
                if( set == null ) {
270
 
                        set = new HashSet< String >();
271
 
                        _contactEmails.put( id, set );
272
 
                }
273
 
                set.add( email );
274
 
        }
275
 
 
276
 
        public boolean hasAssociatedAddress( Long id, String address )
277
 
        {
278
 
                address = normaliseAddress( address );
279
 
                if( address == null ) return false;
280
 
 
281
 
                HashSet< String > set = _contactAddresses.get( id );
282
 
                return set != null && set.contains( address );
283
 
        }
284
 
 
285
 
        public void addAssociatedAddress( Long id, String address )
286
 
        {
287
 
                address = normaliseAddress( address );
288
 
                if( address == null ) return;
289
 
 
290
 
                HashSet< String > set = _contactAddresses.get( id );
291
 
                if( set == null ) {
292
 
                        set = new HashSet< String >();
293
 
                        _contactAddresses.put( id, set );
294
 
                }
295
 
                set.add( address );
296
 
        }
297
 
 
298
 
        public boolean hasAssociatedOrganisation( Long id, String organisation )
299
 
        {
300
 
                organisation = normaliseOrganisation( organisation );
301
 
                if( organisation == null ) return false;
302
 
 
303
 
                HashSet< String > set = _contactOrganisations.get( id );
304
 
                return set != null && set.contains( organisation );
305
 
        }
306
 
 
307
 
        public void addAssociatedOrganisation( Long id, String organisation )
308
 
        {
309
 
                organisation = normaliseOrganisation( organisation );
310
 
                if( organisation == null ) return;
311
 
 
312
 
                HashSet< String > set = _contactOrganisations.get( id );
313
 
                if( set == null ) {
314
 
                        set = new HashSet< String >();
315
 
                        _contactOrganisations.put( id, set );
316
 
                }
317
 
                set.add( organisation );
318
 
        }
319
 
 
320
 
        public boolean hasAssociatedNote( Long id, String note )
321
 
        {
322
 
                note = normaliseNote( note );
323
 
                if( note == null ) return false;
324
 
 
325
 
                HashSet< String > set = _contactNotes.get( id );
326
 
                return set != null && set.contains( note );
327
 
        }
328
 
 
329
 
        public void addAssociatedNote( Long id, String note )
330
 
        {
331
 
                note = normaliseNote( note );
332
 
                if( note == null ) return;
333
 
 
334
 
                HashSet< String > set = _contactNotes.get( id );
335
 
                if( set == null ) {
336
 
                        set = new HashSet< String >();
337
 
                        _contactNotes.put( id, set );
338
 
                }
339
 
                set.add( note );
340
 
        }
341
 
 
342
 
        public boolean hasAssociatedBirthday( Long id, String birthday )
343
 
        {
344
 
                birthday = normaliseBirthday( birthday );
345
 
                if( birthday == null ) return false;
346
 
 
347
 
                String found = _contactBirthdays.get( id );
348
 
                return found != null && found.equalsIgnoreCase( birthday );
349
 
        }
350
 
 
351
 
        public void addAssociatedBirthday( Long id, String birthday )
352
 
        {
353
 
                birthday = normaliseBirthday( birthday );
354
 
                if( birthday == null ) return;
355
 
 
356
 
                _contactBirthdays.put( id, birthday );
357
 
        }
358
 
 
359
 
        static public String normaliseName( String name )
360
 
        {
361
 
                if( name == null ) return null;
362
 
                name = name.trim();
363
 
                return name.length() > 0? name : null;
364
 
        }
365
 
 
366
 
        static public String normalisePhoneNumber( String number )
367
 
        {
368
 
                if( number == null ) return null;
369
 
                number = number.trim().replaceAll( "[-\\(\\) ]", "" );
370
 
                return number.length() > 0? number : null;
371
 
        }
372
 
 
373
 
        static public String normaliseEmailAddress( String email )
374
 
        {
375
 
                if( email == null ) return null;
376
 
                email = email.trim().toLowerCase( Locale.US );
377
 
                return email.length() > 0? email : null;
378
 
        }
379
 
 
380
 
        static public String normaliseOrganisation( String organisation )
381
 
        {
382
 
                if( organisation == null ) return null;
383
 
                organisation = organisation.trim();
384
 
                return organisation.length() > 0? organisation : null;
385
 
        }
386
 
 
387
 
        static public String normaliseAddress( String address )
388
 
        {
389
 
                if( address == null ) return null;
390
 
                address = address.trim();
391
 
                return address.length() > 0? address : null;
392
 
        }
393
 
 
394
 
        static public String normaliseNote( String note )
395
 
        {
396
 
                if( note == null ) return null;
397
 
                note = note.trim();
398
 
                return note.length() > 0? note : null;
399
 
        }
400
 
 
401
 
        static public String normaliseBirthday( String birthday )
402
 
        {
403
 
                if( birthday == null ) return null;
404
 
                birthday = birthday.trim();
405
 
                return birthday.length() > 0? birthday : null;
406
 
        }
407
 
}