1/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package com.android.contacts.util;
17
18
19import android.content.ContentValues;
20import android.content.Context;
21import android.database.Cursor;
22import android.net.Uri;
23import android.net.Uri.Builder;
24import android.provider.ContactsContract;
25import android.provider.ContactsContract.CommonDataKinds.StructuredName;
26import android.text.TextUtils;
27
28import com.android.contacts.model.dataitem.StructuredNameDataItem;
29
30/**
31 * Utility class for converting between a display name and structured name (and vice-versa), via
32 * calls to the contact provider.
33 */
34public class NameConverter {
35
36    /**
37     * The array of fields that comprise a structured name.
38     */
39    public static final String[] STRUCTURED_NAME_FIELDS = new String[] {
40            StructuredName.PREFIX,
41            StructuredName.GIVEN_NAME,
42            StructuredName.MIDDLE_NAME,
43            StructuredName.FAMILY_NAME,
44            StructuredName.SUFFIX
45    };
46
47    /**
48     * Converts the given structured name (provided as ContentValues) into a display name string.
49     * @param context Activity context.
50     * @param values The content values containing values comprising the structured name.
51     * @return
52     */
53    public static String structuredNameToDisplayName(Context context, ContentValues values) {
54        Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name");
55        for (String key : STRUCTURED_NAME_FIELDS) {
56            if (values.containsKey(key)) {
57                appendQueryParameter(builder, key, values.getAsString(key));
58            }
59        }
60        return fetchDisplayName(context, builder.build());
61    }
62
63    /**
64     * Helper method for fetching the display name via the given URI.
65     */
66    private static String fetchDisplayName(Context context, Uri uri) {
67        String displayName = null;
68        Cursor cursor = context.getContentResolver().query(uri, new String[]{
69                StructuredName.DISPLAY_NAME,
70        }, null, null, null);
71
72        if (cursor != null) {
73            try {
74                if (cursor.moveToFirst()) {
75                    displayName = cursor.getString(0);
76                }
77            } finally {
78                cursor.close();
79            }
80        }
81        return displayName;
82    }
83
84    private static void appendQueryParameter(Builder builder, String field, String value) {
85        if (!TextUtils.isEmpty(value)) {
86            builder.appendQueryParameter(field, value);
87        }
88    }
89
90
91    /**
92     * Parses phonetic name and returns parsed data (family, middle, given) as ContentValues.
93     * Parsed data should be {@link StructuredName#PHONETIC_FAMILY_NAME},
94     * {@link StructuredName#PHONETIC_MIDDLE_NAME}, and
95     * {@link StructuredName#PHONETIC_GIVEN_NAME}.
96     * If this method cannot parse given phoneticName, null values will be stored.
97     *
98     * @param phoneticName Phonetic name to be parsed
99     * @param values ContentValues to be used for storing data. If null, new instance will be
100     * created.
101     * @return ContentValues with parsed data. Those data can be null.
102     */
103    public static StructuredNameDataItem parsePhoneticName(String phoneticName,
104            StructuredNameDataItem item) {
105        String family = null;
106        String middle = null;
107        String given = null;
108
109        if (!TextUtils.isEmpty(phoneticName)) {
110            String[] strings = phoneticName.split(" ", 3);
111            switch (strings.length) {
112                case 1:
113                    family = strings[0];
114                    break;
115                case 2:
116                    family = strings[0];
117                    given = strings[1];
118                    break;
119                case 3:
120                    family = strings[0];
121                    middle = strings[1];
122                    given = strings[2];
123                    break;
124            }
125        }
126
127        if (item == null) {
128            item = new StructuredNameDataItem();
129        }
130        item.setPhoneticFamilyName(family);
131        item.setPhoneticMiddleName(middle);
132        item.setPhoneticGivenName(given);
133        return item;
134    }
135
136    /**
137     * Constructs and returns a phonetic full name from given parts.
138     */
139    public static String buildPhoneticName(String family, String middle, String given) {
140        if (!TextUtils.isEmpty(family) || !TextUtils.isEmpty(middle)
141                || !TextUtils.isEmpty(given)) {
142            StringBuilder sb = new StringBuilder();
143            if (!TextUtils.isEmpty(family)) {
144                sb.append(family.trim()).append(' ');
145            }
146            if (!TextUtils.isEmpty(middle)) {
147                sb.append(middle.trim()).append(' ');
148            }
149            if (!TextUtils.isEmpty(given)) {
150                sb.append(given.trim()).append(' ');
151            }
152            sb.setLength(sb.length() - 1); // Yank the last space
153            return sb.toString();
154        } else {
155            return null;
156        }
157    }
158}
159