1da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro/*
2da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro * Copyright (C) 2011 The Android Open Source Project
3da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro *
4da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro * Licensed under the Apache License, Version 2.0 (the "License");
5da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro * you may not use this file except in compliance with the License.
6da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro * You may obtain a copy of the License at
7da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro *
8da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro *      http://www.apache.org/licenses/LICENSE-2.0
9da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro *
10da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro * Unless required by applicable law or agreed to in writing, software
11da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro * distributed under the License is distributed on an "AS IS" BASIS,
12da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro * See the License for the specific language governing permissions and
14da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro * limitations under the License.
15da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro */
16da5bf1cf60beef3de5e651a569fa544293683926Dave Santoropackage com.android.contacts.util;
17da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro
18da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro
19da5bf1cf60beef3de5e651a569fa544293683926Dave Santoroimport android.content.ContentValues;
20da5bf1cf60beef3de5e651a569fa544293683926Dave Santoroimport android.content.Context;
21da5bf1cf60beef3de5e651a569fa544293683926Dave Santoroimport android.database.Cursor;
22da5bf1cf60beef3de5e651a569fa544293683926Dave Santoroimport android.net.Uri;
23da5bf1cf60beef3de5e651a569fa544293683926Dave Santoroimport android.net.Uri.Builder;
24da5bf1cf60beef3de5e651a569fa544293683926Dave Santoroimport android.provider.ContactsContract;
25da5bf1cf60beef3de5e651a569fa544293683926Dave Santoroimport android.provider.ContactsContract.CommonDataKinds.StructuredName;
26da5bf1cf60beef3de5e651a569fa544293683926Dave Santoroimport android.text.TextUtils;
27da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro
28da5bf1cf60beef3de5e651a569fa544293683926Dave Santoroimport java.util.Map;
29da5bf1cf60beef3de5e651a569fa544293683926Dave Santoroimport java.util.TreeMap;
30da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro
31da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro/**
32da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro * Utility class for converting between a display name and structured name (and vice-versa), via
33da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro * calls to the contact provider.
34da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro */
35da5bf1cf60beef3de5e651a569fa544293683926Dave Santoropublic class NameConverter {
36da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro
37da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    /**
38da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * The array of fields that comprise a structured name.
39da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     */
40da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    public static final String[] STRUCTURED_NAME_FIELDS = new String[] {
41da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            StructuredName.PREFIX,
42da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            StructuredName.GIVEN_NAME,
43da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            StructuredName.MIDDLE_NAME,
44da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            StructuredName.FAMILY_NAME,
45da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            StructuredName.SUFFIX
46da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    };
47da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro
48da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    /**
49da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * Converts the given structured name (provided as a map from {@link StructuredName} fields to
50da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * corresponding values) into a display name string.
51da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * <p>
52da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * Note that this operates via a call back to the ContactProvider, but it does not access the
53da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * database, so it should be safe to call from the UI thread.  See
54da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * ContactsProvider2.completeName() for the underlying method call.
55da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * @param context Activity context.
56da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * @param structuredName The structured name map to convert.
57da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * @return The display name computed from the structured name map.
58da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     */
59da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    public static String structuredNameToDisplayName(Context context,
60da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            Map<String, String> structuredName) {
61da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name");
62da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        for (String key : STRUCTURED_NAME_FIELDS) {
63da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            if (structuredName.containsKey(key)) {
64da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro                appendQueryParameter(builder, key, structuredName.get(key));
65da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            }
66da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        }
67da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        return fetchDisplayName(context, builder.build());
68da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    }
69da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro
70da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    /**
71da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * Converts the given structured name (provided as ContentValues) into a display name string.
72da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * @param context Activity context.
73da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * @param values The content values containing values comprising the structured name.
74da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * @return
75da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     */
76da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    public static String structuredNameToDisplayName(Context context, ContentValues values) {
77da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name");
78da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        for (String key : STRUCTURED_NAME_FIELDS) {
79da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            if (values.containsKey(key)) {
80da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro                appendQueryParameter(builder, key, values.getAsString(key));
81da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            }
82da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        }
83da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        return fetchDisplayName(context, builder.build());
84da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    }
85da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro
86da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    /**
87da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * Helper method for fetching the display name via the given URI.
88da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     */
89da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    private static String fetchDisplayName(Context context, Uri uri) {
90da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        String displayName = null;
91da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        Cursor cursor = context.getContentResolver().query(uri, new String[]{
92da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro                StructuredName.DISPLAY_NAME,
93da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        }, null, null, null);
94da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro
95da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        try {
96da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            if (cursor.moveToFirst()) {
97da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro                displayName = cursor.getString(0);
98da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            }
99da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        } finally {
100da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            cursor.close();
101da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        }
102da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        return displayName;
103da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    }
104da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro
105da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    /**
106da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * Converts the given display name string into a structured name (as a map from
107da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * {@link StructuredName} fields to corresponding values).
108da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * <p>
109da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * Note that this operates via a call back to the ContactProvider, but it does not access the
110da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * database, so it should be safe to call from the UI thread.
111da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * @param context Activity context.
112da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * @param displayName The display name to convert.
113da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * @return The structured name map computed from the display name.
114da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     */
115da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    public static Map<String, String> displayNameToStructuredName(Context context,
116da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            String displayName) {
117da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        Map<String, String> structuredName = new TreeMap<String, String>();
118da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        Builder builder = ContactsContract.AUTHORITY_URI.buildUpon().appendPath("complete_name");
119da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro
120da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        appendQueryParameter(builder, StructuredName.DISPLAY_NAME, displayName);
121da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        Cursor cursor = context.getContentResolver().query(builder.build(), STRUCTURED_NAME_FIELDS,
122da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro                null, null, null);
123da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro
124da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        try {
125da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            if (cursor.moveToFirst()) {
126da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro                for (int i = 0; i < STRUCTURED_NAME_FIELDS.length; i++) {
127da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro                    structuredName.put(STRUCTURED_NAME_FIELDS[i], cursor.getString(i));
128da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro                }
129da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            }
130da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        } finally {
131da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            cursor.close();
132da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        }
133da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        return structuredName;
134da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    }
135da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro
136da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    /**
137da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * Converts the given display name string into a structured name (inserting the structured
138da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * values into a new or existing ContentValues object).
139da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * <p>
140da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * Note that this operates via a call back to the ContactProvider, but it does not access the
141da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * database, so it should be safe to call from the UI thread.
142da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * @param context Activity context.
143da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * @param displayName The display name to convert.
144da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * @param contentValues The content values object to place the structured name values into.  If
145da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     *     null, a new one will be created and returned.
146da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     * @return The ContentValues object containing the structured name fields derived from the
147da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     *     display name.
148da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro     */
149da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    public static ContentValues displayNameToStructuredName(Context context, String displayName,
150da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            ContentValues contentValues) {
151da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        if (contentValues == null) {
152da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            contentValues = new ContentValues();
153da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        }
154da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        Map<String, String> mapValues = displayNameToStructuredName(context, displayName);
155da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        for (String key : mapValues.keySet()) {
156da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            contentValues.put(key, mapValues.get(key));
157da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        }
158da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        return contentValues;
159da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    }
160da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro
161da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    private static void appendQueryParameter(Builder builder, String field, String value) {
162da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        if (!TextUtils.isEmpty(value)) {
163da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro            builder.appendQueryParameter(field, value);
164da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro        }
165da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro    }
166da5bf1cf60beef3de5e651a569fa544293683926Dave Santoro}
167