/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 2012 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
 
 
141
 
        public boolean canLookup( CacheIdentifier identifier )
142
 
        {
143
 
                return lookup( identifier ) != null;
144
 
        }
145
 
 
146
 
        /**
147
 
         * Retrieve the contact id of a contact identified by the specified cache
148
 
         * identifier, if it exists.
149
 
         *
150
 
         * @param identifier the cache identifier
151
 
         * @return a contact id, or null
152
 
         */
153
 
        public Long lookup( CacheIdentifier identifier )
154
 
        {
155
 
                switch( identifier.getType() )
156
 
                {
157
 
                case NAME:
158
 
                        return _contactsByName.get( identifier.getDetail() );
159
 
                case ORGANISATION:
160
 
                        return _contactsByOrg.get( identifier.getDetail() );
161
 
                case PRIMARY_NUMBER:
162
 
                        return _contactsByNumber.get( identifier.getDetail() );
163
 
                case PRIMARY_EMAIL:
164
 
                        return _contactsByEmail.get( identifier.getDetail() );
165
 
                }
166
 
                return null;
167
 
        }
168
 
 
169
 
        /**
170
 
         * Remove any cache entry that is identified by the cache identifier.
171
 
         *
172
 
         * @param identifier the cache identifier
173
 
         * @return the contact id of the contact that was removed, or null
174
 
         */
175
 
        public Long removeLookup( CacheIdentifier identifier )
176
 
        {
177
 
                switch( identifier.getType() )
178
 
                {
179
 
                case NAME:
180
 
                        return _contactsByName.remove( identifier.getDetail() );
181
 
                case ORGANISATION:
182
 
                        return _contactsByOrg.remove( identifier.getDetail() );
183
 
                case PRIMARY_NUMBER:
184
 
                        return _contactsByNumber.remove( identifier.getDetail() );
185
 
                case PRIMARY_EMAIL:
186
 
                        return _contactsByEmail.remove( identifier.getDetail() );
187
 
                }
188
 
                return null;
189
 
        }
190
 
 
191
 
        /**
192
 
         * Add a lookup from a contact identifier to a contact id to the cache.
193
 
         *
194
 
         * @param identifier the cache identifier
195
 
         * @param id teh contact id
196
 
         */
197
 
        public void addLookup( CacheIdentifier identifier, Long id )
198
 
        {
199
 
                switch( identifier.getType() )
200
 
                {
201
 
                case NAME:
202
 
                        _contactsByName.put( identifier.getDetail(), id );
203
 
                        break;
204
 
                case ORGANISATION:
205
 
                        _contactsByOrg.put( identifier.getDetail(), id );
206
 
                        break;
207
 
                case PRIMARY_NUMBER:
208
 
                        _contactsByNumber.put( identifier.getDetail(), id );
209
 
                        break;
210
 
                case PRIMARY_EMAIL:
211
 
                        _contactsByEmail.put( identifier.getDetail(), id );
212
 
                        break;
213
 
                }
214
 
        }
215
 
 
216
 
        /**
217
 
         * Remove any data that is associated with an contact id.
218
 
         *
219
 
         * @param id
220
 
         */
221
 
        public void removeAssociatedData( Long id )
222
 
        {
223
 
                _contactNumbers.remove( id );
224
 
                _contactEmails.remove( id );
225
 
                _contactAddresses.remove( id );
226
 
                _contactOrganisations.remove( id );
227
 
                _contactNotes.remove( id );
228
 
        }
229
 
 
230
 
        public boolean hasAssociatedNumber( Long id, String number )
231
 
        {
232
 
                number = normalisePhoneNumber( number );
233
 
                if( number == null ) return false;
234
 
 
235
 
                HashSet< String > set = _contactNumbers.get( id );
236
 
                return set != null && set.contains( number );
237
 
        }
238
 
 
239
 
        public void addAssociatedNumber( Long id, String number )
240
 
        {
241
 
                number = normalisePhoneNumber( number );
242
 
                if( number == null ) return;
243
 
 
244
 
                HashSet< String > set = _contactNumbers.get( id );
245
 
                if( set == null ) {
246
 
                        set = new HashSet< String >();
247
 
                        _contactNumbers.put( id, set );
248
 
                }
249
 
                set.add( number );
250
 
        }
251
 
 
252
 
        public boolean hasAssociatedEmail( Long id, String email )
253
 
        {
254
 
                email = normaliseEmailAddress( email );
255
 
                if( email == null ) return false;
256
 
 
257
 
                HashSet< String > set = _contactEmails.get( id );
258
 
                return set != null && set.contains( email );
259
 
        }
260
 
 
261
 
        public void addAssociatedEmail( Long id, String email )
262
 
        {
263
 
                email = normaliseEmailAddress( email );
264
 
                if( email == null ) return;
265
 
 
266
 
                HashSet< String > set = _contactEmails.get( id );
267
 
                if( set == null ) {
268
 
                        set = new HashSet< String >();
269
 
                        _contactEmails.put( id, set );
270
 
                }
271
 
                set.add( email );
272
 
        }
273
 
 
274
 
        public boolean hasAssociatedAddress( Long id, String address )
275
 
        {
276
 
                address = normaliseAddress( address );
277
 
                if( address == null ) return false;
278
 
 
279
 
                HashSet< String > set = _contactAddresses.get( id );
280
 
                return set != null && set.contains( address );
281
 
        }
282
 
 
283
 
        public void addAssociatedAddress( Long id, String address )
284
 
        {
285
 
                address = normaliseAddress( address );
286
 
                if( address == null ) return;
287
 
 
288
 
                HashSet< String > set = _contactAddresses.get( id );
289
 
                if( set == null ) {
290
 
                        set = new HashSet< String >();
291
 
                        _contactAddresses.put( id, set );
292
 
                }
293
 
                set.add( address );
294
 
        }
295
 
 
296
 
        public boolean hasAssociatedOrganisation( Long id, String organisation )
297
 
        {
298
 
                organisation = normaliseOrganisation( organisation );
299
 
                if( organisation == null ) return false;
300
 
 
301
 
                HashSet< String > set = _contactOrganisations.get( id );
302
 
                return set != null && set.contains( organisation );
303
 
        }
304
 
 
305
 
        public void addAssociatedOrganisation( Long id, String organisation )
306
 
        {
307
 
                organisation = normaliseOrganisation( organisation );
308
 
                if( organisation == null ) return;
309
 
 
310
 
                HashSet< String > set = _contactOrganisations.get( id );
311
 
                if( set == null ) {
312
 
                        set = new HashSet< String >();
313
 
                        _contactOrganisations.put( id, set );
314
 
                }
315
 
                set.add( organisation );
316
 
        }
317
 
 
318
 
        public boolean hasAssociatedNote( Long id, String note )
319
 
        {
320
 
                note = normaliseNote( note );
321
 
                if( note == null ) return false;
322
 
 
323
 
                HashSet< String > set = _contactNotes.get( id );
324
 
                return set != null && set.contains( note );
325
 
        }
326
 
 
327
 
        public void addAssociatedNote( Long id, String note )
328
 
        {
329
 
                note = normaliseNote( note );
330
 
                if( note == null ) return;
331
 
 
332
 
                HashSet< String > set = _contactNotes.get( id );
333
 
                if( set == null ) {
334
 
                        set = new HashSet< String >();
335
 
                        _contactNotes.put( id, set );
336
 
                }
337
 
                set.add( note );
338
 
        }
339
 
 
340
 
        static public String normaliseName( String name )
341
 
        {
342
 
                if( name == null ) return null;
343
 
                name = name.trim();
344
 
                return name.length() > 0? name : null;
345
 
        }
346
 
 
347
 
        static public String normalisePhoneNumber( String number )
348
 
        {
349
 
                if( number == null ) return null;
350
 
                number = number.trim().replaceAll( "[-\\(\\) ]", "" );
351
 
                return number.length() > 0? number : null;
352
 
        }
353
 
 
354
 
        static public String normaliseEmailAddress( String email )
355
 
        {
356
 
                if( email == null ) return null;
357
 
                email = email.trim().toLowerCase( Locale.US );
358
 
                return email.length() > 0? email : null;
359
 
        }
360
 
 
361
 
        static public String normaliseOrganisation( String organisation )
362
 
        {
363
 
                if( organisation == null ) return null;
364
 
                organisation = organisation.trim();
365
 
                return organisation.length() > 0? organisation : null;
366
 
        }
367
 
 
368
 
        static public String normaliseAddress( String address )
369
 
        {
370
 
                if( address == null ) return null;
371
 
                address = address.trim();
372
 
                return address.length() > 0? address : null;
373
 
        }
374
 
 
375
 
        static public String normaliseNote( String note )
376
 
        {
377
 
                if( note == null ) return null;
378
 
                note = note.trim();
379
 
                return note.length() > 0? note : null;
380
 
        }
381
 
}