FileDocCategorySizeDatePackage
VCardComposer.javaAPI DocAndroid 1.5 API12189Wed May 06 22:41:56 BST 2009android.syncml.pim.vcard

VCardComposer

public class VCardComposer extends Object
Compose VCard string

Fields Summary
public static final int
VERSION_VCARD21_INT
public static final int
VERSION_VCARD30_INT
private String
mNewline
A new line
private StringBuilder
mResult
The composed string
private static final HashSet
emailTypes
The email's type
private static final HashSet
phoneTypes
private static final String
TAG
private static final HashMap
phoneTypeMap
private static final HashMap
emailTypeMap
Constructors Summary
public VCardComposer()


      
    
Methods Summary
private voidappendContactMethodStr(java.util.List contactMList, int version)
Loop append ADR / EMAIL property.


        HashMap<String, String> emailMap = new HashMap<String, String>();
        String joinMark = version == VERSION_VCARD21_INT ? ";" : ",";
        for (ContactStruct.ContactMethod contactMethod : contactMList) {
            // same with v2.1 and v3.0
            switch (Integer.parseInt(contactMethod.kind)) {
            case Contacts.KIND_EMAIL:
                String mailType = "INTERNET";
                if (!isNull(contactMethod.data)) {
                    int methodType = new Integer(contactMethod.type).intValue();
                    if (emailTypeMap.containsKey(methodType)) {
                        mailType = emailTypeMap.get(methodType);
                    } else if (emailTypes.contains(contactMethod.label
                            .toUpperCase())) {
                        mailType = contactMethod.label.toUpperCase();
                    }
                    if (emailMap.containsKey(contactMethod.data)) {
                        mailType = emailMap.get(contactMethod.data) + joinMark
                                + mailType;
                    }
                    emailMap.put(contactMethod.data, mailType);
                }
                break;
            case Contacts.KIND_POSTAL:
                if (!isNull(contactMethod.data)) {
                    mResult.append("ADR;TYPE=POSTAL:").append(
                            foldingString(contactMethod.data, version)).append(
                            mNewline);
                }
                break;
            default:
                break;
            }
        }
        for (Map.Entry<String, String> email : emailMap.entrySet()) {
            if (version == VERSION_VCARD21_INT) {
                mResult.append("EMAIL;");
            } else {
                mResult.append("EMAIL;TYPE=");
            }
            mResult.append(email.getValue()).append(":").append(email.getKey())
                    .append(mNewline);
        }
    
private voidappendNameStr(java.lang.String name)
Build FN and N property. format N's value.

param
name the name of the contact

        mResult.append("FN:").append(name).append(mNewline);
        mResult.append("N:").append(name).append(mNewline);
        /*
         * if(name.indexOf(";") > 0)
         * mResult.append("N:").append(name).append(mNewline); else
         * if(name.indexOf(" ") > 0) mResult.append("N:").append(name.replace(' ',
         * ';')). append(mNewline); else
         * mResult.append("N:").append(name).append("; ").append(mNewline);
         */
    
private voidappendPhoneStr(java.util.List phoneList, int version)
Loop append TEL property.

        HashMap<String, String> numMap = new HashMap<String, String>();
        String joinMark = version == VERSION_VCARD21_INT ? ";" : ",";

        for (ContactStruct.PhoneData phone : phoneList) {
            String type;
            if (!isNull(phone.data)) {
                type = getPhoneTypeStr(phone);
                if (version == VERSION_VCARD30_INT && type.indexOf(";") != -1) {
                    type = type.replace(";", ",");
                }
                if (numMap.containsKey(phone.data)) {
                    type = numMap.get(phone.data) + joinMark + type;
                }
                numMap.put(phone.data, type);
            }
        }

        for (Map.Entry<String, String> num : numMap.entrySet()) {
            if (version == VERSION_VCARD21_INT) {
                mResult.append("TEL;");
            } else { // vcard3.0
                mResult.append("TEL;TYPE=");
            }
            mResult.append(num.getValue()).append(":").append(num.getKey())
                    .append(mNewline);
        }
    
private voidappendPhotoStr(byte[] bytes, java.lang.String type, int version)
Build LOGO property. format LOGO's param and encode value as base64.

param
bytes the binary string to be converted
param
type the type of the content
param
version the version of vcard

        String value, apptype, encodingStr;
        try {
            value = foldingString(new String(Base64.encodeBase64(bytes, true)),
                    version);
        } catch (Exception e) {
            throw new VCardException(e.getMessage());
        }

        if (isNull(type)) {
            type = "image/jpeg";
        }
        if (type.indexOf("jpeg") > 0) {
            apptype = "JPEG";
        } else if (type.indexOf("gif") > 0) {
            apptype = "GIF";
        } else if (type.indexOf("bmp") > 0) {
            apptype = "BMP";
        } else {
            apptype = type.substring(type.indexOf("/")).toUpperCase();
        }

        mResult.append("LOGO;TYPE=").append(apptype);
        if (version == VERSION_VCARD21_INT) {
            encodingStr = ";ENCODING=BASE64:";
            value = value + mNewline;
        } else if (version == VERSION_VCARD30_INT) {
            encodingStr = ";ENCODING=b:";
        } else {
            return;
        }
        mResult.append(encodingStr).append(value).append(mNewline);
    
public java.lang.StringcreateVCard(ContactStruct struct, int vcardversion)
Create a vCard String.

param
struct see more from ContactStruct class
param
vcardversion MUST be VERSION_VCARD21 /VERSION_VCARD30
return
vCard string
throws
VCardException struct.name is null /vcardversion not match


     
        phoneTypeMap.put(Contacts.Phones.TYPE_HOME, "HOME");
        phoneTypeMap.put(Contacts.Phones.TYPE_MOBILE, "CELL");
        phoneTypeMap.put(Contacts.Phones.TYPE_WORK, "WORK");
        // FAX_WORK not exist in vcard spec. The approximate is the combine of
        // WORK and FAX, here only map to FAX
        phoneTypeMap.put(Contacts.Phones.TYPE_FAX_WORK, "WORK;FAX");
        phoneTypeMap.put(Contacts.Phones.TYPE_FAX_HOME, "HOME;FAX");
        phoneTypeMap.put(Contacts.Phones.TYPE_PAGER, "PAGER");
        phoneTypeMap.put(Contacts.Phones.TYPE_OTHER, "X-OTHER");
        emailTypeMap.put(Contacts.ContactMethods.TYPE_HOME, "HOME");
        emailTypeMap.put(Contacts.ContactMethods.TYPE_WORK, "WORK");
    

        mResult = new StringBuilder();
        // check exception:
        if (struct.name == null || struct.name.trim().equals("")) {
            throw new VCardException(" struct.name MUST have value.");
        }
        if (vcardversion == VERSION_VCARD21_INT) {
            mNewline = "\r\n";
        } else if (vcardversion == VERSION_VCARD30_INT) {
            mNewline = "\n";
        } else {
            throw new VCardException(
                    " version not match VERSION_VCARD21 or VERSION_VCARD30.");
        }
        // build vcard:
        mResult.append("BEGIN:VCARD").append(mNewline);

        if (vcardversion == VERSION_VCARD21_INT) {
            mResult.append("VERSION:2.1").append(mNewline);
        } else {
            mResult.append("VERSION:3.0").append(mNewline);
        }

        if (!isNull(struct.name)) {
            appendNameStr(struct.name);
        }

        if (!isNull(struct.company)) {
            mResult.append("ORG:").append(struct.company).append(mNewline);
        }

        if (!isNull(struct.notes)) {
            mResult.append("NOTE:").append(
                    foldingString(struct.notes, vcardversion)).append(mNewline);
        }

        if (!isNull(struct.title)) {
            mResult.append("TITLE:").append(
                    foldingString(struct.title, vcardversion)).append(mNewline);
        }

        if (struct.photoBytes != null) {
            appendPhotoStr(struct.photoBytes, struct.photoType, vcardversion);
        }

        if (struct.phoneList != null) {
            appendPhoneStr(struct.phoneList, vcardversion);
        }

        if (struct.contactmethodList != null) {
            appendContactMethodStr(struct.contactmethodList, vcardversion);
        }

        mResult.append("END:VCARD").append(mNewline);
        return mResult.toString();
    
private java.lang.StringfoldingString(java.lang.String str, int version)
Alter str to folding supported format.

param
str the string to be folded
param
version the vcard version
return
the folded string

        if (str.endsWith("\r\n")) {
            str = str.substring(0, str.length() - 2);
        } else if (str.endsWith("\n")) {
            str = str.substring(0, str.length() - 1);
        } else {
            return null;
        }

        str = str.replaceAll("\r\n", "\n");
        if (version == VERSION_VCARD21_INT) {
            return str.replaceAll("\n", "\r\n ");
        } else if (version == VERSION_VCARD30_INT) {
            return str.replaceAll("\n", "\n ");
        } else {
            return null;
        }
    
private java.lang.StringgetPhoneTypeStr(android.syncml.pim.vcard.ContactStruct.PhoneData phone)


        int phoneType = Integer.parseInt(phone.type);
        String typeStr, label;

        if (phoneTypeMap.containsKey(phoneType)) {
            typeStr = phoneTypeMap.get(phoneType);
        } else if (phoneType == Contacts.Phones.TYPE_CUSTOM) {
            label = phone.label.toUpperCase();
            if (phoneTypes.contains(label) || label.startsWith("X-")) {
                typeStr = label;
            } else {
                typeStr = "X-CUSTOM-" + label;
            }
        } else {
            // TODO: need be updated with the provider's future changes
            typeStr = "VOICE"; // the default type is VOICE in spec.
        }
        return typeStr;
    
private booleanisNull(java.lang.String str)

        if (str == null || str.trim().equals("")) {
            return true;
        }
        return false;