/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/org/waxworlds/edam/importcontacts/VCFImporter.java

  • Committer: edam
  • Date: 2011-04-22 15:36:06 UTC
  • Revision ID: edam@waxworlds.org-20110422153606-9x9l0nbmvx6oxfxu
- pulled contacts cache out in to seperate class

Show diffs side-by-side

added added

removed removed

1
1
/*
2
2
 * VCFImporter.java
3
3
 *
4
 
 * Copyright (C) 2009 to 2011 Tim Marston <edam@waxworlds.org>
 
4
 * Copyright (C) 2009 Tim Marston <edam@waxworlds.org>
5
5
 *
6
6
 * This file is part of the Import Contacts program (hereafter referred
7
7
 * to as "this program"). For more information, see
34
34
import java.nio.ByteBuffer;
35
35
import java.util.ArrayList;
36
36
import java.util.Arrays;
37
 
import java.util.HashMap;
38
37
import java.util.HashSet;
39
38
import java.util.Iterator;
40
39
import java.util.List;
44
43
import java.util.regex.Matcher;
45
44
import java.util.regex.Pattern;
46
45
 
47
 
import org.waxworlds.edam.importcontacts.Importer.ContactData.ExtraDetail;
48
 
 
49
46
import android.content.SharedPreferences;
50
47
import android.provider.Contacts;
51
48
import android.provider.Contacts.PhonesColumns;
333
330
        private class VCard extends ContactData
334
331
        {
335
332
                private final static int NAMELEVEL_NONE = 0;
336
 
                private final static int NAMELEVEL_FN = 1;
337
 
                private final static int NAMELEVEL_N = 2;
 
333
                private final static int NAMELEVEL_ORG = 1;
 
334
                private final static int NAMELEVEL_FN = 2;
 
335
                private final static int NAMELEVEL_N = 3;
338
336
 
339
337
                private final static int MULTILINE_NONE = 0;
340
338
                private final static int MULTILINE_ENCODED = 1; // v2.1 quoted-printable
347
345
                private int _parser_multiline_state = MULTILINE_NONE;
348
346
                private String _parser_current_name_and_params = null;
349
347
                private String _parser_buffered_value_so_far = "";
350
 
                private String _cached_organisation = null;
351
 
                private String _cached_title = null;
352
348
 
353
349
                protected class UnencodeResult
354
350
                {
625
621
                                        parseFN( name_param_parts, complete_value );
626
622
                                else if( name_param_parts[ 0 ].equals( "ORG" ) )
627
623
                                        parseORG( name_param_parts, complete_value );
628
 
                                else if( name_param_parts[ 0 ].equals( "TITLE" ) )
629
 
                                        parseTITLE( name_param_parts, complete_value );
630
624
                                else if( name_param_parts[ 0 ].equals( "TEL" ) )
631
625
                                        parseTEL( name_param_parts, complete_value );
632
626
                                else if( name_param_parts[ 0 ].equals( "EMAIL" ) )
689
683
                }
690
684
 
691
685
                private void parseN( String[] params, String value )
 
686
                        throws ParseException, SkipContactException,
 
687
                        AbortImportException
692
688
                {
693
689
                        // already got a better name?
694
690
                        if( _name_level >= NAMELEVEL_N ) return;
706
702
                        // set name
707
703
                        setName( value );
708
704
                        _name_level = NAMELEVEL_N;
 
705
 
 
706
                        // check now to see if we need to import this contact (to avoid
 
707
                        // parsing the rest of the vCard unnecessarily)
 
708
                        if( !isImportRequired( getName() ) )
 
709
                                throw new SkipContactException();
709
710
                }
710
711
 
711
712
                private void parseFN( String[] params, String value )
 
713
                        throws ParseException, SkipContactException
712
714
                {
713
715
                        // already got a better name?
714
716
                        if( _name_level >= NAMELEVEL_FN ) return;
719
721
                }
720
722
 
721
723
                private void parseORG( String[] params, String value )
 
724
                        throws ParseException, SkipContactException
722
725
                {
 
726
                        // already got a better name?
 
727
                        if( _name_level >= NAMELEVEL_ORG ) return;
 
728
 
723
729
                        // get org parts
724
730
                        String[] org_parts = splitValueBySemicolon( value );
725
 
                        if( org_parts == null || org_parts.length < 1 ) return;
726
 
 
727
 
                        // build organisation name
728
 
                        StringBuilder builder = new StringBuilder(
729
 
                                String.valueOf( org_parts[ 0 ] ) );
730
 
                        for( int a = 1; a < org_parts.length; a++ )
731
 
                                builder.append( ", " ).append( org_parts[ a ] );
732
 
                        String organisation = builder.toString();
733
 
 
734
 
                        // set organisation name (using a title we've previously found)
735
 
                        addOrganisation( organisation, _cached_title, true );
736
 
 
737
 
                        // if we've not previously found a title, store this organisation
738
 
                        // name (we'll need it when we find a title to update the
739
 
                        // organisation, by name), else if we *have* previously found a
740
 
                        // title, clear it (since we just used it)
741
 
                        if( _cached_title == null )
742
 
                                _cached_organisation = organisation;
743
 
                        else
744
 
                                _cached_title = null;
745
 
                }
746
 
 
747
 
                private void parseTITLE( String[] params, String value )
748
 
                {
749
 
                        // if we previously had an organisation, look it up and append this
750
 
                        // title to it
751
 
                        if( _cached_organisation != null && hasOrganisations() ) {
752
 
                                HashMap< String, ExtraDetail > datas = getOrganisations();
753
 
                                ExtraDetail detail = datas.get( _cached_organisation );
754
 
                                if( detail != null )
755
 
                                        detail.setExtra( value );
756
 
                        }
757
 
 
758
 
                        // same as when handling organisation, if we've not previously found
759
 
                        // an organisation we store this title, else we clear it (since we
760
 
                        // just appended this title to it)
761
 
                        if( _cached_organisation == null )
762
 
                                _cached_title = value;
763
 
                        else
764
 
                                _cached_organisation = null;
 
731
 
 
732
                        // build name
 
733
                        if( org_parts.length > 1 && org_parts[ 0 ].length() == 0 )
 
734
                                value = org_parts[ 1 ];
 
735
                        else if( org_parts.length > 1 && org_parts[ 1 ].length() > 0 )
 
736
                                value = org_parts[ 0 ] + ", " + org_parts[ 1 ];
 
737
                        else
 
738
                                value = org_parts[ 0 ];
 
739
 
 
740
                        // set name
 
741
                        setName( value );
 
742
                        _name_level = NAMELEVEL_ORG;
765
743
                }
766
744
 
767
745
                private void parseTEL( String[] params, String value )
 
746
                        throws ParseException
768
747
                {
769
748
                        if( value.length() == 0 ) return;
770
749
 
774
753
 
775
754
                        // here's the logic...
776
755
                        boolean preferred = types.contains( "PREF" );
777
 
                        int type;
 
756
                        int type = PhonesColumns.TYPE_MOBILE;
 
757
                        if( types.contains( "VOICE" ) )
 
758
                                if( types.contains( "WORK" ) )
 
759
                                        type = PhonesColumns.TYPE_WORK;
 
760
                                else
 
761
                                        type = PhonesColumns.TYPE_HOME;
 
762
                        else if( types.contains( "CELL" ) || types.contains( "VIDEO" ) )
 
763
                                type = PhonesColumns.TYPE_MOBILE;
778
764
                        if( types.contains( "FAX" ) )
779
765
                                if( types.contains( "HOME" ) )
780
766
                                        type = PhonesColumns.TYPE_FAX_HOME;
781
767
                                else
782
768
                                        type = PhonesColumns.TYPE_FAX_WORK;
783
 
                        else if( types.contains( "CELL" ) || types.contains( "VIDEO" ) )
784
 
                                type = PhonesColumns.TYPE_MOBILE;
785
 
                        else if( types.contains( "PAGER" ) )
 
769
                        if( types.contains( "PAGER" ) )
786
770
                                type = PhonesColumns.TYPE_PAGER;
787
 
                        else if( types.contains( "WORK" ) )
788
 
                                type = PhonesColumns.TYPE_WORK;
789
 
                        else
790
 
                                type = PhonesColumns.TYPE_HOME;
791
771
 
792
772
                        // add phone number
793
 
                        addNumber( value, type, preferred );
 
773
                        addPhone( value, type, preferred );
794
774
                }
795
775
 
796
776
                public void parseEMAIL( String[] params, String value )
 
777
                        throws ParseException
797
778
                {
798
779
                        if( value.length() == 0 ) return;
799
780
 
802
783
 
803
784
                        // add email address
804
785
                        boolean preferred = types.contains( "PREF" );
805
 
                        int type;
806
786
                        if( types.contains( "WORK" ) )
807
 
                                type = Contacts.ContactMethods.TYPE_WORK;
 
787
                                addEmail( value, Contacts.ContactMethods.TYPE_WORK, preferred );
808
788
                        else
809
 
                                type = Contacts.ContactMethods.TYPE_HOME;
810
 
 
811
 
                        addEmail( value, type, preferred );
 
789
                                addEmail( value, Contacts.ContactMethods.TYPE_HOME, preferred );
812
790
                }
813
791
 
814
792
                private void parseADR( String[] params, String value )
 
793
                        throws ParseException, SkipContactException
815
794
                {
816
795
                        // get address parts
817
796
                        String[] adr_parts = splitValueBySemicolon( value );
827
806
                                "PREF", "WORK", "HOME", "INTERNET" ) );
828
807
 
829
808
                        // add address
830
 
                        int type;
831
809
                        if( types.contains( "WORK" ) )
832
 
                                type = Contacts.ContactMethods.TYPE_WORK;
 
810
                                addAddress( value, Contacts.ContactMethods.TYPE_WORK );
833
811
                        else
834
 
                                type = Contacts.ContactMethods.TYPE_HOME;
835
 
 
836
 
                        addAddress( value, type );
 
812
                                addAddress( value, Contacts.ContactMethods.TYPE_HOME);
837
813
                }
838
814
 
839
815
                public void finaliseParsing()
844
820
                        if( _version == null && _buffers != null )
845
821
                                throw new ParseException( R.string.error_vcf_malformed );
846
822
 
847
 
                        // check if we should import this contact
848
 
                        try {
849
 
                                if( !isImportRequired( this ) )
850
 
                                        throw new SkipContactException();
851
 
                        }
852
 
                        catch( ContactNeedsMoreInfoException e ) {
853
 
                                throw new ParseException( R.string.error_vcf_notenoughinfo );
854
 
                        }
 
823
                        //  missing name properties?
 
824
                        if( _name_level == NAMELEVEL_NONE )
 
825
                                throw new ParseException( R.string.error_vcf_noname );
 
826
 
 
827
                        // check if we should import this one? If we've already got an 'N'-
 
828
                        // type name, this will already have been done by parseN() so we
 
829
                        // mustn't do this here (or it could prompt twice!)
 
830
                        if( _name_level < NAMELEVEL_N && !isImportRequired( getName() ) )
 
831
                                throw new SkipContactException();
855
832
                }
856
833
 
857
834
                private String checkParam( String[] params, String name )