/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/Importer.java

  • Committer: edam
  • Date: 2012-12-19 17:51:35 UTC
  • Revision ID: tim@ed.am-20121219175135-1cpuafp76jg1ib1p
added preliminary (buggy) ContactsContract backend

Show diffs side-by-side

added added

removed removed

1
1
/*
2
2
 * Importer.java
3
3
 *
4
 
 * Copyright (C) 2009 to 2013 Tim Marston <tim@ed.am>
 
4
 * Copyright (C) 2009 to 2012 Tim Marston <tim@ed.am>
5
5
 *
6
6
 * This file is part of the Import Contacts program (hereafter referred
7
 
 * to as "this program").  For more information, see
 
7
 * to as "this program"). For more information, see
8
8
 * http://ed.am/dev/android/import-contacts
9
9
 *
10
10
 * This program is free software: you can redistribute it and/or modify
141
141
                protected HashMap< String, PreferredDetail > _numbers = null;
142
142
                protected HashMap< String, PreferredDetail > _emails = null;
143
143
                protected HashMap< String, TypeDetail > _addresses = null;
144
 
                protected HashSet< String > _notes = null;
145
 
                protected String _birthday = null;
146
144
 
147
145
                private ContactsCache.CacheIdentifier _cache_identifier = null;
148
146
 
186
184
 
187
185
                        // if this is the first organisation added, or it's a preferred
188
186
                        // organisation and the current primary organisation isn't, then
189
 
                        // record this as the primary organisation
 
187
                        // record this as the primary organisation.
190
188
                        if( _primary_organisation == null ||
191
189
                                ( is_preferred && !_primary_organisation_is_preferred ) )
192
190
                        {
240
238
                        // and the current primary number isn't, or this number is on equal
241
239
                        // standing with the primary number in terms of preference and it is
242
240
                        // a voice number and the primary number isn't, then record this as
243
 
                        // the primary number
 
241
                        // the primary number.
244
242
                        if( _primary_number == null ||
245
243
                                ( is_preferred && !_primary_number_is_preferred ) ||
246
244
                                ( is_preferred == _primary_number_is_preferred &&
292
290
 
293
291
                        // if this is the first email added, or it's a preferred email and
294
292
                        // the current primary organisation isn't, then record this as the
295
 
                        // primary email
 
293
                        // primary email.
296
294
                        if( _primary_email == null ||
297
295
                                ( is_preferred && !_primary_email_is_preferred ) )
298
296
                        {
346
344
                        return _addresses;
347
345
                }
348
346
 
349
 
                protected void addNote( String note )
350
 
                {
351
 
                        if( _notes == null ) _notes = new HashSet< String >();
352
 
                        if( !_notes.contains( note ) )
353
 
                                _notes.add( note );
354
 
                }
355
 
 
356
 
                public boolean hasNotes()
357
 
                {
358
 
                        return _notes != null && _notes.size() > 0;
359
 
                }
360
 
 
361
 
                public HashSet< String > getNotes()
362
 
                {
363
 
                        return _notes;
364
 
                }
365
 
 
366
 
                public void setBirthday( String birthday )
367
 
                {
368
 
                        _birthday = birthday;
369
 
                }
370
 
 
371
 
                public boolean hasBirthday()
372
 
                {
373
 
                        return _birthday != null;
374
 
                }
375
 
 
376
 
                public String getBirthday()
377
 
                {
378
 
                        return _birthday;
379
 
                }
380
 
 
381
347
                protected void finalise()
382
348
                        throws ContactNotIdentifiableException
383
349
                {
384
 
                        // Ensure that if there is a primary number, it is preferred so
385
 
                        // that there is always one preferred number.  Android will assign
 
350
                        // ensure that if there is a primary number, it is preferred so
 
351
                        // that there is always one preferred number. Android will assign
386
352
                        // preference to one anyway so we might as well decide one sensibly.
387
353
                        if( _primary_number != null ) {
388
354
                                PreferredDetail data = _numbers.get( _primary_number );
406
372
 
407
373
                        // create a cache identifier from this contact data, which can be
408
374
                        // used to look-up an existing contact
409
 
                        _cache_identifier = ContactsCache.CacheIdentifier.factory( this );
 
375
                        _cache_identifier = ContactsCache.createIdentifier( this );
410
376
                        if( _cache_identifier == null )
411
377
                                throw new ContactNotIdentifiableException();
412
378
                }
433
399
                        Matcher m = p.matcher( email );
434
400
                        if( m.matches() ) {
435
401
                                String[] bits = email.split( "@" );
436
 
                                return bits[ 0 ] + "@" +
437
 
                                        bits[ 1 ].toLowerCase( Locale.ENGLISH );
 
402
                                return bits[ 0 ] + "@" + bits[ 1 ].toLowerCase( Locale.US );
438
403
                        }
439
404
                        return null;
440
405
                }
544
509
                finish( ACTION_ABORT );
545
510
        }
546
511
 
547
 
        protected void showContinueOrAbort( int res ) throws AbortImportException
548
 
        {
549
 
                showContinueOrAbort( _doit.getText( res ).toString() );
550
 
        }
551
 
 
552
 
        synchronized protected void showContinueOrAbort( String message )
 
512
        protected void showFatalError( int res ) throws AbortImportException
 
513
        {
 
514
                showFatalError( _doit.getText( res ).toString() );
 
515
        }
 
516
 
 
517
        synchronized protected void showFatalError( String message )
 
518
                        throws AbortImportException
 
519
        {
 
520
                checkAbort();
 
521
                _doit._handler.sendMessage( Message.obtain(
 
522
                        _doit._handler, Doit.MESSAGE_ERROR, message ) );
 
523
                try {
 
524
                        wait();
 
525
                }
 
526
                catch( InterruptedException e ) { }
 
527
 
 
528
                // no need to check if an abortion happened during the wait, we are
 
529
                // about to finish anyway!
 
530
                finish( ACTION_ABORT );
 
531
        }
 
532
 
 
533
        protected boolean showContinue( int res ) throws AbortImportException
 
534
        {
 
535
                return showContinue( _doit.getText( res ).toString() );
 
536
        }
 
537
 
 
538
        synchronized protected boolean showContinue( String message )
553
539
                        throws AbortImportException
554
540
        {
555
541
                checkAbort();
560
546
                }
561
547
                catch( InterruptedException e ) { }
562
548
 
563
 
                // if we're aborting, there's no need to check if an abortion happened
564
 
                // during the wait
565
 
                if( _response == RESPONSE_NEGATIVE )
566
 
                        finish( ACTION_ABORT );
567
 
                else
568
 
                        checkAbort();
 
549
                // check if an abortion happened during the wait
 
550
                checkAbort();
 
551
 
 
552
                return _response == RESPONSE_POSITIVE;
569
553
        }
570
554
 
571
555
        protected void setProgressMessage( int res ) throws AbortImportException
625
609
        /**
626
610
         * Should we skip a contact, given whether it exists or not and the current
627
611
         * merge setting?  This routine handles throwing up a prompt, if required.
628
 
         *
629
612
         * @param contact_detail the display name of the contact
630
613
         * @param exists true if this contact matches one in the cache
631
614
         * @param merge_setting the merge setting to use
685
668
        {
686
669
                checkAbort();
687
670
 
688
 
                // It is expected that we use contact.getCacheIdentifier() here.  The
 
671
                // It is expected that we use contact.getCacheIdentifier() here. The
689
672
                // contact we are passed should have been successfully finalise()d,
690
673
                // which includes generating a valid cache identifier.
691
674
                ContactsCache.CacheIdentifier cache_identifier =
758
741
                                importContactAddresses( id, contact.getAddresses() );
759
742
                        if( contact.hasOrganisations() )
760
743
                                importContactOrganisations( id, contact.getOrganisations() );
761
 
                        if( contact.hasNotes() )
762
 
                                importContactNotes( id, contact.getNotes() );
763
 
                        if( contact.hasBirthday() )
764
 
                                importContactBirthday( id, contact.getBirthday() );
765
744
                }
766
745
                catch( Backend.ContactCreationException e )
767
746
                {
780
759
                        String number = i.next();
781
760
                        ContactData.PreferredDetail data = datas.get( number );
782
761
 
783
 
                        // We don't want to add this number if it's crap, or it already
784
 
                        // exists (which would cause a duplicate to be created).  We don't
785
 
                        // take in to account the type when checking for duplicates.  This
786
 
                        // is intentional: types aren't really very reliable.  We assume
787
 
                        // that if the number exists at all, it doesn't need importing.
788
 
                        // Because of this, we also can't update the cache (which we don't
789
 
                        // need to anyway, so it's not a problem).
 
762
                        // we don't want to add this number if it's crap, or it already
 
763
                        // exists (which would cause a duplicate to be created). We don't
 
764
                        // take in to account the type when checking for duplicates. This is
 
765
                        // intentional: types aren't really very reliable. We assume that
 
766
                        // if the number exists at all, it doesn't need importing. Because
 
767
                        // of this, we also can't update the cache (which we don't need to
 
768
                        // anyway, so it's not a problem).
790
769
                        if( _contacts_cache.hasAssociatedNumber( id, number ) )
791
770
                                continue;
792
771
 
811
790
                        ContactData.PreferredDetail data = datas.get( email );
812
791
 
813
792
                        // we don't want to add this email address if it exists already or
814
 
                        // we would introduce duplicates
 
793
                        // we would introduce duplicates.
815
794
                        if( _contacts_cache.hasAssociatedEmail( id, email ) )
816
795
                                continue;
817
796
 
874
853
                }
875
854
        }
876
855
 
877
 
        private void importContactNotes( Long id, HashSet< String > datas )
878
 
                throws ContactCreationException
879
 
        {
880
 
                // add notes
881
 
                Iterator< String > i = datas.iterator();
882
 
                while( i.hasNext() ) {
883
 
                        String note = i.next();
884
 
 
885
 
                        // we don't want to add this note if it exists already or we would
886
 
                        // introduce duplicates
887
 
                        if( _contacts_cache.hasAssociatedNote( id, note ) )
888
 
                                continue;
889
 
 
890
 
                        // add note
891
 
                        _backend.addContactNote( id, note );
892
 
 
893
 
                        // and add this note to the cache to prevent a addition of duplicate
894
 
                        // date from another file
895
 
                        _contacts_cache.addAssociatedNote( id, note );
896
 
                }
897
 
        }
898
 
 
899
 
        private void importContactBirthday( Long id, String birthday )
900
 
                throws ContactCreationException
901
 
        {
902
 
                // we don't want to import this birthday if it already exists
903
 
                if( _contacts_cache.hasAssociatedBirthday( id, birthday ) )
904
 
                        return;
905
 
 
906
 
                // add birthday
907
 
                _backend.addContactBirthday( id, birthday );
908
 
 
909
 
                // and update the cache
910
 
                _contacts_cache.addAssociatedBirthday( id, birthday );
911
 
        }
912
 
 
913
856
        synchronized protected void checkAbort() throws AbortImportException
914
857
        {
915
858
                if( _abort ) {