summaryrefslogtreecommitdiffstats
path: root/src/com/android/browser/search/SearchEngineInfo.java
blob: ec304f64c965d2ecbe386931ee62ca7732eb584b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
/*
 * Copyright (C) 2010 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.android.browser.search;

import android.content.Context;
import android.content.res.Resources;
import android.content.res.Resources.NotFoundException;
import android.text.TextUtils;
import android.util.Log;

import com.android.browser.R;

import java.net.URLEncoder;
import java.util.Arrays;
import java.util.Locale;

/**
 * Loads and holds data for a given web search engine.
 */
public class SearchEngineInfo {

    private static String TAG = "SearchEngineInfo";

    // The fields of a search engine data array, defined in the same order as they appear in the
    // all_search_engines.xml file.
    // If you are adding/removing to this list, remember to update NUM_FIELDS below.
    private static final int FIELD_LABEL = 0;
    private static final int FIELD_KEYWORD = 1;
    private static final int FIELD_FAVICON_URI = 2;
    private static final int FIELD_SEARCH_URI = 3;
    private static final int FIELD_ENCODING = 4;
    private static final int FIELD_SUGGEST_URI = 5;
    private static final int NUM_FIELDS = 6;

    // The OpenSearch URI template parameters that we support.
    private static final String PARAMETER_LANGUAGE = "{language}";
    private static final String PARAMETER_SEARCH_TERMS = "{searchTerms}";
    private static final String PARAMETER_INPUT_ENCODING = "{inputEncoding}";

    private final String mName;

    // The array of strings defining this search engine. The array values are in the same order as
    // the above enumeration definition.
    private final String[] mSearchEngineData;

    /**
     * @throws IllegalArgumentException If the name does not refer to a valid search engine
     */
    public SearchEngineInfo(Context context, String name) throws IllegalArgumentException {
        mName = name;
        Resources res = context.getResources();

        String packageName = R.class.getPackage().getName();
        int id_data = res.getIdentifier(name, "array", packageName);
        if (id_data == 0) {
            throw new IllegalArgumentException("No resources found for " + name);
        }
        mSearchEngineData = res.getStringArray(id_data);

        if (mSearchEngineData == null) {
            throw new IllegalArgumentException("No data found for " + name);
        }
        if (mSearchEngineData.length != NUM_FIELDS) {
                throw new IllegalArgumentException(
                        name + " has invalid number of fields - " + mSearchEngineData.length);
        }
        if (TextUtils.isEmpty(mSearchEngineData[FIELD_SEARCH_URI])) {
            throw new IllegalArgumentException(name + " has an empty search URI");
        }

        // Add the current language/country information to the URIs.
        Locale locale = context.getResources().getConfiguration().locale;
        StringBuilder language = new StringBuilder(locale.getLanguage());
        if (!TextUtils.isEmpty(locale.getCountry())) {
            language.append('-');
            language.append(locale.getCountry());
        }

        String language_str = language.toString();
        mSearchEngineData[FIELD_SEARCH_URI] =
                mSearchEngineData[FIELD_SEARCH_URI].replace(PARAMETER_LANGUAGE, language_str);
        mSearchEngineData[FIELD_SUGGEST_URI] =
                mSearchEngineData[FIELD_SUGGEST_URI].replace(PARAMETER_LANGUAGE, language_str);

        // Default to UTF-8 if not specified.
        String enc = mSearchEngineData[FIELD_ENCODING];
        if (TextUtils.isEmpty(enc)) {
            enc = "UTF-8";
            mSearchEngineData[FIELD_ENCODING] = enc;
        }

        // Add the input encoding method to the URI.
        mSearchEngineData[FIELD_SEARCH_URI] =
                mSearchEngineData[FIELD_SEARCH_URI].replace(PARAMETER_INPUT_ENCODING, enc);
        mSearchEngineData[FIELD_SUGGEST_URI] =
                mSearchEngineData[FIELD_SUGGEST_URI].replace(PARAMETER_INPUT_ENCODING, enc);
    }

    public String getName() {
        return mName;
    }

    public String getLabel() {
        return mSearchEngineData[FIELD_LABEL];
    }

    /**
     * Returns the URI for launching a web search with the given query (or null if there was no
     * data available for this search engine).
     */
    public String getSearchUriForQuery(String query) {
        return getFormattedUri(searchUri(), query);
    }

    /**
     * Returns the URI for retrieving web search suggestions for the given query (or null if there
     * was no data available for this search engine).
     */
    public String getSuggestUriForQuery(String query) {
        return getFormattedUri(suggestUri(), query);
    }

    public boolean supportsSuggestions() {
        return !TextUtils.isEmpty(suggestUri());
    }

    public String faviconUri() {
        return mSearchEngineData[FIELD_FAVICON_URI];
    }

    private String suggestUri() {
        return mSearchEngineData[FIELD_SUGGEST_URI];
    }

    private String searchUri() {
        return mSearchEngineData[FIELD_SEARCH_URI];
    }

    /**
     * Formats a launchable uri out of the template uri by replacing the template parameters with
     * actual values.
     */
    private String getFormattedUri(String templateUri, String query) {
        if (TextUtils.isEmpty(templateUri)) {
            return null;
        }

        // Encode the query terms in the requested encoding (and fallback to UTF-8 if not).
        String enc = mSearchEngineData[FIELD_ENCODING];
        try {
            return templateUri.replace(PARAMETER_SEARCH_TERMS, URLEncoder.encode(query, enc));
        } catch (java.io.UnsupportedEncodingException e) {
            Log.e(TAG, "Exception occured when encoding query " + query + " to " + enc);
            return null;
        }
    }

    @Override
    public String toString() {
        return "SearchEngineInfo{" + Arrays.toString(mSearchEngineData) + "}";
    }

}