~slub.team/goobi-indexserver/3.x

« back to all changes in this revision

Viewing changes to lucene/contrib/facet/src/java/org/apache/lucene/facet/index/CategoryDocumentBuilder.java

  • Committer: Sebastian Meyer
  • Date: 2012-08-03 09:12:40 UTC
  • Revision ID: sebastian.meyer@slub-dresden.de-20120803091240-x6861b0vabq1xror
Remove Lucene and Solr source code and add patches instead
Fix Bug #985487: Auto-suggestion for the search interface

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
package org.apache.lucene.facet.index;
2
 
 
3
 
import java.io.IOException;
4
 
import java.util.ArrayList;
5
 
import java.util.HashMap;
6
 
import java.util.List;
7
 
import java.util.Map;
8
 
import java.util.Map.Entry;
9
 
 
10
 
import org.apache.lucene.analysis.TokenStream;
11
 
import org.apache.lucene.document.Document;
12
 
import org.apache.lucene.document.Field;
13
 
 
14
 
import org.apache.lucene.facet.index.attributes.CategoryAttribute;
15
 
import org.apache.lucene.facet.index.attributes.CategoryAttributesIterable;
16
 
import org.apache.lucene.facet.index.categorypolicy.OrdinalPolicy;
17
 
import org.apache.lucene.facet.index.categorypolicy.PathPolicy;
18
 
import org.apache.lucene.facet.index.params.DefaultFacetIndexingParams;
19
 
import org.apache.lucene.facet.index.params.FacetIndexingParams;
20
 
import org.apache.lucene.facet.index.streaming.CategoryAttributesStream;
21
 
import org.apache.lucene.facet.index.streaming.CategoryListTokenizer;
22
 
import org.apache.lucene.facet.index.streaming.CategoryParentsStream;
23
 
import org.apache.lucene.facet.index.streaming.CategoryTokenizer;
24
 
import org.apache.lucene.facet.index.streaming.CountingListTokenizer;
25
 
import org.apache.lucene.facet.taxonomy.CategoryPath;
26
 
import org.apache.lucene.facet.taxonomy.TaxonomyWriter;
27
 
 
28
 
/**
29
 
 * Licensed to the Apache Software Foundation (ASF) under one or more
30
 
 * contributor license agreements.  See the NOTICE file distributed with
31
 
 * this work for additional information regarding copyright ownership.
32
 
 * The ASF licenses this file to You under the Apache License, Version 2.0
33
 
 * (the "License"); you may not use this file except in compliance with
34
 
 * the License.  You may obtain a copy of the License at
35
 
 *
36
 
 *     http://www.apache.org/licenses/LICENSE-2.0
37
 
 *
38
 
 * Unless required by applicable law or agreed to in writing, software
39
 
 * distributed under the License is distributed on an "AS IS" BASIS,
40
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
41
 
 * See the License for the specific language governing permissions and
42
 
 * limitations under the License.
43
 
 */
44
 
 
45
 
/**
46
 
 * A utility class which allows attachment of {@link CategoryPath}s or
47
 
 * {@link CategoryAttribute}s to a given document using a taxonomy.<br>
48
 
 * Construction could be done with either a given {@link FacetIndexingParams} or
49
 
 * the default implementation {@link DefaultFacetIndexingParams}.<br>
50
 
 * A CategoryDocumentBuilder can be reused by repeatedly setting the categories
51
 
 * and building the document. Categories are provided either as
52
 
 * {@link CategoryAttribute} elements through {@link #setCategories(Iterable)},
53
 
 * or as {@link CategoryPath} elements through
54
 
 * {@link #setCategoryPaths(Iterable)}.
55
 
 * <p>
56
 
 * Note that both {@link #setCategories(Iterable)} and
57
 
 * {@link #setCategoryPaths(Iterable)} return this
58
 
 * {@link CategoryDocumentBuilder}, allowing the following pattern: {@code new
59
 
 * CategoryDocumentBuilder(taxonomy,
60
 
 * params).setCategories(categories).build(doc)}.
61
 
 * 
62
 
 * @lucene.experimental
63
 
 */
64
 
public class CategoryDocumentBuilder {
65
 
 
66
 
  /**
67
 
   * A {@link TaxonomyWriter} for adding categories and retrieving their
68
 
   * ordinals.
69
 
   */
70
 
  protected final TaxonomyWriter taxonomyWriter;
71
 
 
72
 
  /**
73
 
   * Parameters to be used when indexing categories.
74
 
   */
75
 
  protected final FacetIndexingParams indexingParams;
76
 
 
77
 
  /**
78
 
   * A list of fields which is filled at ancestors' construction and used
79
 
   * during {@link CategoryDocumentBuilder#build(Document)}.
80
 
   */
81
 
  protected final ArrayList<Field> fieldList = new ArrayList<Field>();
82
 
 
83
 
  protected Map<String, List<CategoryAttribute>> categoriesMap;
84
 
 
85
 
  /**
86
 
   * Creating a facets document builder with default facet indexing
87
 
   * parameters.<br>
88
 
   * See:
89
 
   * {@link #CategoryDocumentBuilder(TaxonomyWriter, FacetIndexingParams)}
90
 
   * 
91
 
   * @param taxonomyWriter
92
 
   *            to which new categories will be added, as well as translating
93
 
   *            known categories to ordinals
94
 
   * @throws IOException
95
 
   * 
96
 
   */
97
 
  public CategoryDocumentBuilder(TaxonomyWriter taxonomyWriter)
98
 
      throws IOException {
99
 
    this(taxonomyWriter, new DefaultFacetIndexingParams());
100
 
  }
101
 
 
102
 
  /**
103
 
   * Creating a facets document builder with a given facet indexing parameters
104
 
   * object.<br>
105
 
   * 
106
 
   * @param taxonomyWriter
107
 
   *            to which new categories will be added, as well as translating
108
 
   *            known categories to ordinals
109
 
   * @param params
110
 
   *            holds all parameters the indexing process should use such as
111
 
   *            category-list parameters
112
 
   * @throws IOException
113
 
   */
114
 
  public CategoryDocumentBuilder(TaxonomyWriter taxonomyWriter,
115
 
      FacetIndexingParams params) throws IOException {
116
 
    this.taxonomyWriter = taxonomyWriter;
117
 
    this.indexingParams = params;
118
 
    this.categoriesMap = new HashMap<String, List<CategoryAttribute>>();
119
 
  }
120
 
 
121
 
  /**
122
 
   * Set the categories of the document builder from an {@link Iterable} of
123
 
   * {@link CategoryPath} objects.
124
 
   * 
125
 
   * @param categoryPaths
126
 
   *            An iterable of CategoryPath objects which holds the categories
127
 
   *            (facets) which will be added to the document at
128
 
   *            {@link #build(Document)}
129
 
   * @return This CategoryDocumentBuilder, to enable this one line call:
130
 
   *         {@code new} {@link #CategoryDocumentBuilder(TaxonomyWriter)}.
131
 
   *         {@link #setCategoryPaths(Iterable)}.{@link #build(Document)}.
132
 
   * @throws IOException
133
 
   */
134
 
  public CategoryDocumentBuilder setCategoryPaths(
135
 
      Iterable<CategoryPath> categoryPaths) throws IOException {
136
 
    if (categoryPaths == null) {
137
 
      fieldList.clear();
138
 
      return this;
139
 
    }
140
 
    return setCategories(new CategoryAttributesIterable(categoryPaths));
141
 
  }
142
 
 
143
 
  /**
144
 
   * Set the categories of the document builder from an {@link Iterable} of
145
 
   * {@link CategoryAttribute} objects.
146
 
   * 
147
 
   * @param categories
148
 
   *            An iterable of {@link CategoryAttribute} objects which holds
149
 
   *            the categories (facets) which will be added to the document at
150
 
   *            {@link #build(Document)}
151
 
   * @return This CategoryDocumentBuilder, to enable this one line call:
152
 
   *         {@code new} {@link #CategoryDocumentBuilder(TaxonomyWriter)}.
153
 
   *         {@link #setCategories(Iterable)}.{@link #build(Document)}.
154
 
   * @throws IOException
155
 
   */
156
 
  public CategoryDocumentBuilder setCategories(
157
 
      Iterable<CategoryAttribute> categories) throws IOException {
158
 
    fieldList.clear();
159
 
    if (categories == null) {
160
 
      return this;
161
 
    }
162
 
 
163
 
    // get field-name to a list of facets mapping as different facets could
164
 
    // be added to different category-lists on different fields
165
 
    fillCategoriesMap(categories);
166
 
 
167
 
    // creates a different stream for each different field
168
 
    for (Entry<String, List<CategoryAttribute>> e : categoriesMap
169
 
        .entrySet()) {
170
 
      // create a category attributes stream for the array of facets
171
 
      CategoryAttributesStream categoryAttributesStream = new CategoryAttributesStream(
172
 
          e.getValue());
173
 
 
174
 
      // Set a suitable {@link TokenStream} using
175
 
      // CategoryParentsStream, followed by CategoryListTokenizer and
176
 
      // CategoryTokenizer composition (the ordering of the last two is
177
 
      // not mandatory).
178
 
      CategoryParentsStream parentsStream = (CategoryParentsStream) getParentsStream(categoryAttributesStream);
179
 
      CategoryListTokenizer categoryListTokenizer = getCategoryListTokenizer(parentsStream);
180
 
      CategoryTokenizer stream = getCategoryTokenizer(categoryListTokenizer);
181
 
 
182
 
      // Finally creating a suitable field with stream and adding it to a
183
 
      // master field-list, used during the build process (see
184
 
      // super.build())
185
 
      fieldList.add(new Field(e.getKey(), stream));
186
 
    }
187
 
 
188
 
    return this;
189
 
  }
190
 
 
191
 
  /**
192
 
   * Get a stream of categories which includes the parents, according to
193
 
   * policies defined in indexing parameters.
194
 
   * 
195
 
   * @param categoryAttributesStream
196
 
   *            The input stream
197
 
   * @return The parents stream.
198
 
   * @see OrdinalPolicy OrdinalPolicy (for policy of adding category tokens for parents)
199
 
   * @see PathPolicy PathPolicy (for policy of adding category <b>list</b> tokens for parents)
200
 
   */
201
 
  protected TokenStream getParentsStream(
202
 
      CategoryAttributesStream categoryAttributesStream) {
203
 
    return new CategoryParentsStream(categoryAttributesStream,
204
 
        taxonomyWriter, indexingParams);
205
 
  }
206
 
 
207
 
  /**
208
 
   * Fills the categories mapping between a field name and a list of
209
 
   * categories that belongs to it according to this builder's
210
 
   * {@link FacetIndexingParams} object
211
 
   * 
212
 
   * @param categories
213
 
   *            Iterable over the category attributes
214
 
   */
215
 
  protected void fillCategoriesMap(Iterable<CategoryAttribute> categories)
216
 
      throws IOException {
217
 
    categoriesMap.clear();
218
 
 
219
 
    // for-each category
220
 
    for (CategoryAttribute category : categories) {
221
 
      // extracting the field-name to which this category belongs
222
 
      String fieldName = indexingParams.getCategoryListParams(
223
 
          category.getCategoryPath()).getTerm().field();
224
 
 
225
 
      // getting the list of categories which belongs to that field
226
 
      List<CategoryAttribute> list = categoriesMap.get(fieldName);
227
 
 
228
 
      // if no such list exists
229
 
      if (list == null) {
230
 
        // adding a new one to the map
231
 
        list = new ArrayList<CategoryAttribute>();
232
 
        categoriesMap.put(fieldName, list);
233
 
      }
234
 
 
235
 
      // adding the new category to the list
236
 
      list.add(category.clone());
237
 
    }
238
 
  }
239
 
 
240
 
  /**
241
 
   * Get a category list tokenizer (or a series of such tokenizers) to create
242
 
   * the <b>category list tokens</b>.
243
 
   * 
244
 
   * @param categoryStream
245
 
   *            A stream containing {@link CategoryAttribute} with the
246
 
   *            relevant data.
247
 
   * @return The category list tokenizer (or series of tokenizers) to be used
248
 
   *         in creating category list tokens.
249
 
   */
250
 
  protected CategoryListTokenizer getCategoryListTokenizer(
251
 
      TokenStream categoryStream) {
252
 
    return getCountingListTokenizer(categoryStream);
253
 
  }
254
 
 
255
 
  /**
256
 
   * Get a {@link CountingListTokenizer} for creating counting list token.
257
 
   * 
258
 
   * @param categoryStream
259
 
   *            A stream containing {@link CategoryAttribute}s with the
260
 
   *            relevant data.
261
 
   * @return A counting list tokenizer to be used in creating counting list
262
 
   *         token.
263
 
   */
264
 
  protected CountingListTokenizer getCountingListTokenizer(
265
 
      TokenStream categoryStream) {
266
 
    return new CountingListTokenizer(categoryStream, indexingParams);
267
 
  }
268
 
 
269
 
  /**
270
 
   * Get a {@link CategoryTokenizer} to create the <b>category tokens</b>.
271
 
   * This method can be overridden for adding more attributes to the category
272
 
   * tokens.
273
 
   * 
274
 
   * @param categoryStream
275
 
   *            A stream containing {@link CategoryAttribute} with the
276
 
   *            relevant data.
277
 
   * @return The {@link CategoryTokenizer} to be used in creating category
278
 
   *         tokens.
279
 
   * @throws IOException
280
 
   */
281
 
  protected CategoryTokenizer getCategoryTokenizer(TokenStream categoryStream)
282
 
      throws IOException {
283
 
    return new CategoryTokenizer(categoryStream, indexingParams);
284
 
  }
285
 
 
286
 
  /** Adds the fields created in one of the "set" methods to the document */
287
 
  public Document build(Document doc) {
288
 
    for (Field f : fieldList) {
289
 
      f.setOmitNorms(true);
290
 
      doc.add(f);
291
 
    }
292
 
    return doc;
293
 
  }
294
 
 
295
 
}