1/* 2 * Copyright (C) 2010 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.browser.search; 17 18import android.content.Context; 19import android.content.res.Resources; 20import android.content.res.Resources.NotFoundException; 21import android.text.TextUtils; 22import android.util.Log; 23 24import com.android.browser.R; 25 26import java.net.URLEncoder; 27import java.util.Arrays; 28import java.util.Locale; 29 30/** 31 * Loads and holds data for a given web search engine. 32 */ 33public class SearchEngineInfo { 34 35 private static String TAG = "SearchEngineInfo"; 36 37 // The fields of a search engine data array, defined in the same order as they appear in the 38 // all_search_engines.xml file. 39 // If you are adding/removing to this list, remember to update NUM_FIELDS below. 40 private static final int FIELD_LABEL = 0; 41 private static final int FIELD_KEYWORD = 1; 42 private static final int FIELD_FAVICON_URI = 2; 43 private static final int FIELD_SEARCH_URI = 3; 44 private static final int FIELD_ENCODING = 4; 45 private static final int FIELD_SUGGEST_URI = 5; 46 private static final int NUM_FIELDS = 6; 47 48 // The OpenSearch URI template parameters that we support. 49 private static final String PARAMETER_LANGUAGE = "{language}"; 50 private static final String PARAMETER_SEARCH_TERMS = "{searchTerms}"; 51 private static final String PARAMETER_INPUT_ENCODING = "{inputEncoding}"; 52 53 private final String mName; 54 55 // The array of strings defining this search engine. The array values are in the same order as 56 // the above enumeration definition. 57 private final String[] mSearchEngineData; 58 59 /** 60 * @throws IllegalArgumentException If the name does not refer to a valid search engine 61 */ 62 public SearchEngineInfo(Context context, String name) throws IllegalArgumentException { 63 mName = name; 64 Resources res = context.getResources(); 65 66 String packageName = R.class.getPackage().getName(); 67 int id_data = res.getIdentifier(name, "array", packageName); 68 if (id_data == 0) { 69 throw new IllegalArgumentException("No resources found for " + name); 70 } 71 mSearchEngineData = res.getStringArray(id_data); 72 73 if (mSearchEngineData == null) { 74 throw new IllegalArgumentException("No data found for " + name); 75 } 76 if (mSearchEngineData.length != NUM_FIELDS) { 77 throw new IllegalArgumentException( 78 name + " has invalid number of fields - " + mSearchEngineData.length); 79 } 80 if (TextUtils.isEmpty(mSearchEngineData[FIELD_SEARCH_URI])) { 81 throw new IllegalArgumentException(name + " has an empty search URI"); 82 } 83 84 // Add the current language/country information to the URIs. 85 Locale locale = context.getResources().getConfiguration().locale; 86 StringBuilder language = new StringBuilder(locale.getLanguage()); 87 if (!TextUtils.isEmpty(locale.getCountry())) { 88 language.append('-'); 89 language.append(locale.getCountry()); 90 } 91 92 String language_str = language.toString(); 93 mSearchEngineData[FIELD_SEARCH_URI] = 94 mSearchEngineData[FIELD_SEARCH_URI].replace(PARAMETER_LANGUAGE, language_str); 95 mSearchEngineData[FIELD_SUGGEST_URI] = 96 mSearchEngineData[FIELD_SUGGEST_URI].replace(PARAMETER_LANGUAGE, language_str); 97 98 // Default to UTF-8 if not specified. 99 String enc = mSearchEngineData[FIELD_ENCODING]; 100 if (TextUtils.isEmpty(enc)) { 101 enc = "UTF-8"; 102 mSearchEngineData[FIELD_ENCODING] = enc; 103 } 104 105 // Add the input encoding method to the URI. 106 mSearchEngineData[FIELD_SEARCH_URI] = 107 mSearchEngineData[FIELD_SEARCH_URI].replace(PARAMETER_INPUT_ENCODING, enc); 108 mSearchEngineData[FIELD_SUGGEST_URI] = 109 mSearchEngineData[FIELD_SUGGEST_URI].replace(PARAMETER_INPUT_ENCODING, enc); 110 } 111 112 public String getName() { 113 return mName; 114 } 115 116 public String getLabel() { 117 return mSearchEngineData[FIELD_LABEL]; 118 } 119 120 /** 121 * Returns the URI for launching a web search with the given query (or null if there was no 122 * data available for this search engine). 123 */ 124 public String getSearchUriForQuery(String query) { 125 return getFormattedUri(searchUri(), query); 126 } 127 128 /** 129 * Returns the URI for retrieving web search suggestions for the given query (or null if there 130 * was no data available for this search engine). 131 */ 132 public String getSuggestUriForQuery(String query) { 133 return getFormattedUri(suggestUri(), query); 134 } 135 136 public boolean supportsSuggestions() { 137 return !TextUtils.isEmpty(suggestUri()); 138 } 139 140 public String faviconUri() { 141 return mSearchEngineData[FIELD_FAVICON_URI]; 142 } 143 144 private String suggestUri() { 145 return mSearchEngineData[FIELD_SUGGEST_URI]; 146 } 147 148 private String searchUri() { 149 return mSearchEngineData[FIELD_SEARCH_URI]; 150 } 151 152 /** 153 * Formats a launchable uri out of the template uri by replacing the template parameters with 154 * actual values. 155 */ 156 private String getFormattedUri(String templateUri, String query) { 157 if (TextUtils.isEmpty(templateUri)) { 158 return null; 159 } 160 161 // Encode the query terms in the requested encoding (and fallback to UTF-8 if not). 162 String enc = mSearchEngineData[FIELD_ENCODING]; 163 try { 164 return templateUri.replace(PARAMETER_SEARCH_TERMS, URLEncoder.encode(query, enc)); 165 } catch (java.io.UnsupportedEncodingException e) { 166 Log.e(TAG, "Exception occured when encoding query " + query + " to " + enc); 167 return null; 168 } 169 } 170 171 @Override 172 public String toString() { 173 return "SearchEngineInfo{" + Arrays.toString(mSearchEngineData) + "}"; 174 } 175 176} 177