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 */
16
17package com.android.quicksearchbox;
18
19import com.android.quicksearchbox.util.Factory;
20
21import android.content.Context;
22import android.util.Log;
23
24import java.util.ArrayList;
25import java.util.Collection;
26import java.util.HashSet;
27import java.util.concurrent.Executor;
28
29/**
30 * Creates corpora.
31 */
32public class SearchableCorpusFactory implements CorpusFactory {
33
34    private static final String TAG = "QSB.SearchableCorpusFactory";
35
36    private final Context mContext;
37
38    private final Config mConfig;
39
40    private final SearchSettings mSettings;
41
42    private final Factory<Executor> mWebCorpusExecutorFactory;
43
44    public SearchableCorpusFactory(Context context, Config config, SearchSettings settings,
45            Factory<Executor> webCorpusExecutorFactory) {
46        mContext = context;
47        mConfig = config;
48        mSettings = settings;
49        mWebCorpusExecutorFactory = webCorpusExecutorFactory;
50    }
51
52    public Collection<Corpus> createCorpora(Sources sources) {
53        ArrayList<Corpus> corpora = new ArrayList<Corpus>();
54        addSpecialCorpora(corpora, sources);
55        addSingleSourceCorpora(corpora, sources);
56        return corpora;
57    }
58
59    protected Context getContext() {
60        return mContext;
61    }
62
63    protected Config getConfig() {
64        return mConfig;
65    }
66
67    protected Executor createWebCorpusExecutor() {
68        return mWebCorpusExecutorFactory.create();
69    }
70
71    /**
72     * Adds any corpora that are not simple single source corpora.
73     *
74     * @param corpora List to add corpora to.
75     * @param sources All available sources.
76     */
77    protected void addSpecialCorpora(ArrayList<Corpus> corpora, Sources sources) {
78        addCorpus(corpora, createWebCorpus(sources));
79        addCorpus(corpora, createAppsCorpus(sources));
80    }
81
82    /**
83     * Adds corpora for all sources that are not already used by a corpus.
84     *
85     * @param corpora List to add the new corpora to. Corpora will not be created for the sources
86     *        used by corpora already in this list.
87     * @param sources Sources to create corpora for.
88     */
89    protected void addSingleSourceCorpora(ArrayList<Corpus> corpora, Sources sources) {
90        // Set of all sources that are already used
91        HashSet<Source> claimedSources = new HashSet<Source>();
92        for (Corpus specialCorpus : corpora) {
93            claimedSources.addAll(specialCorpus.getSources());
94        }
95
96        // Creates corpora for all unclaimed sources
97        for (Source source : sources.getSources()) {
98            if (!claimedSources.contains(source)) {
99                addCorpus(corpora, createSingleSourceCorpus(source));
100            }
101        }
102    }
103
104    private void addCorpus(ArrayList<Corpus> corpora, Corpus corpus) {
105        if (corpus != null) corpora.add(corpus);
106    }
107
108    protected Corpus createWebCorpus(Sources sources) {
109        Source webSource = getWebSource(sources);
110        if (webSource != null && !webSource.canRead()) {
111            Log.w(TAG, "Can't read web source " + webSource.getName());
112            webSource = null;
113        }
114        Source browserSource = getBrowserSource(sources);
115        if (browserSource != null && !browserSource.canRead()) {
116            Log.w(TAG, "Can't read browser source " + browserSource.getName());
117            browserSource = null;
118        }
119        Executor executor = createWebCorpusExecutor();
120        return new WebCorpus(mContext, mConfig, mSettings, executor, webSource, browserSource);
121    }
122
123    protected Corpus createAppsCorpus(Sources sources) {
124        Source appsSource = getAppsSource(sources);
125        return new AppsCorpus(mContext, mConfig, appsSource);
126    }
127
128    protected Corpus createSingleSourceCorpus(Source source) {
129        if (!source.canRead()) return null;
130        return new SingleSourceCorpus(mContext, mConfig, source);
131    }
132
133    protected Source getWebSource(Sources sources) {
134        return sources.getWebSearchSource();
135    }
136
137    protected Source getBrowserSource(Sources sources) {
138        String name = getContext().getString(R.string.browser_search_component);
139        return sources.getSource(name);
140    }
141
142    protected Source getAppsSource(Sources sources) {
143        String name = getContext().getString(R.string.installed_apps_component);
144        return sources.getSource(name);
145    }
146
147}
148