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

« back to all changes in this revision

Viewing changes to lucene/contrib/analyzers/common/src/java/org/apache/lucene/analysis/ngram/EdgeNGramTokenizer.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.analysis.ngram;
2
 
 
3
 
/**
4
 
 * Licensed to the Apache Software Foundation (ASF) under one or more
5
 
 * contributor license agreements.  See the NOTICE file distributed with
6
 
 * this work for additional information regarding copyright ownership.
7
 
 * The ASF licenses this file to You under the Apache License, Version 2.0
8
 
 * (the "License"); you may not use this file except in compliance with
9
 
 * the License.  You may obtain a copy of the License at
10
 
 *
11
 
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 
 *
13
 
 * Unless required by applicable law or agreed to in writing, software
14
 
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 
 * See the License for the specific language governing permissions and
17
 
 * limitations under the License.
18
 
 */
19
 
 
20
 
import org.apache.lucene.analysis.Tokenizer;
21
 
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
22
 
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
23
 
import org.apache.lucene.util.AttributeSource;
24
 
 
25
 
import java.io.IOException;
26
 
import java.io.Reader;
27
 
 
28
 
/**
29
 
 * Tokenizes the input from an edge into n-grams of given size(s).
30
 
 * <p>
31
 
 * This {@link Tokenizer} create n-grams from the beginning edge or ending edge of a input token.
32
 
 * MaxGram can't be larger than 1024 because of limitation.
33
 
 * </p>
34
 
 */
35
 
public final class EdgeNGramTokenizer extends Tokenizer {
36
 
  public static final Side DEFAULT_SIDE = Side.FRONT;
37
 
  public static final int DEFAULT_MAX_GRAM_SIZE = 1;
38
 
  public static final int DEFAULT_MIN_GRAM_SIZE = 1;
39
 
  
40
 
  private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class);
41
 
  private final OffsetAttribute offsetAtt = addAttribute(OffsetAttribute.class);
42
 
 
43
 
  /** Specifies which side of the input the n-gram should be generated from */
44
 
  public static enum Side {
45
 
 
46
 
    /** Get the n-gram from the front of the input */
47
 
    FRONT {
48
 
      @Override
49
 
      public String getLabel() { return "front"; }
50
 
    },
51
 
 
52
 
    /** Get the n-gram from the end of the input */
53
 
    BACK  {
54
 
      @Override
55
 
      public String getLabel() { return "back"; }
56
 
    };
57
 
 
58
 
    public abstract String getLabel();
59
 
 
60
 
    // Get the appropriate Side from a string
61
 
    public static Side getSide(String sideName) {
62
 
      if (FRONT.getLabel().equals(sideName)) {
63
 
        return FRONT;
64
 
      }
65
 
      if (BACK.getLabel().equals(sideName)) {
66
 
        return BACK;
67
 
      }
68
 
      return null;
69
 
    }
70
 
  }
71
 
 
72
 
  private int minGram;
73
 
  private int maxGram;
74
 
  private int gramSize;
75
 
  private Side side;
76
 
  private boolean started = false;
77
 
  private int inLen;
78
 
  private String inStr;
79
 
 
80
 
 
81
 
  /**
82
 
   * Creates EdgeNGramTokenizer that can generate n-grams in the sizes of the given range
83
 
   *
84
 
   * @param input {@link Reader} holding the input to be tokenized
85
 
   * @param side the {@link Side} from which to chop off an n-gram
86
 
   * @param minGram the smallest n-gram to generate
87
 
   * @param maxGram the largest n-gram to generate
88
 
   */
89
 
  public EdgeNGramTokenizer(Reader input, Side side, int minGram, int maxGram) {
90
 
    super(input);
91
 
    init(side, minGram, maxGram);
92
 
  }
93
 
 
94
 
  /**
95
 
   * Creates EdgeNGramTokenizer that can generate n-grams in the sizes of the given range
96
 
   *
97
 
   * @param source {@link AttributeSource} to use
98
 
   * @param input {@link Reader} holding the input to be tokenized
99
 
   * @param side the {@link Side} from which to chop off an n-gram
100
 
   * @param minGram the smallest n-gram to generate
101
 
   * @param maxGram the largest n-gram to generate
102
 
   */
103
 
  public EdgeNGramTokenizer(AttributeSource source, Reader input, Side side, int minGram, int maxGram) {
104
 
    super(source, input);
105
 
    init(side, minGram, maxGram);
106
 
  }
107
 
 
108
 
  /**
109
 
   * Creates EdgeNGramTokenizer that can generate n-grams in the sizes of the given range
110
 
   * 
111
 
   * @param factory {@link org.apache.lucene.util.AttributeSource.AttributeFactory} to use
112
 
   * @param input {@link Reader} holding the input to be tokenized
113
 
   * @param side the {@link Side} from which to chop off an n-gram
114
 
   * @param minGram the smallest n-gram to generate
115
 
   * @param maxGram the largest n-gram to generate
116
 
   */
117
 
  public EdgeNGramTokenizer(AttributeFactory factory, Reader input, Side side, int minGram, int maxGram) {
118
 
    super(factory, input);
119
 
    init(side, minGram, maxGram);
120
 
  }
121
 
  
122
 
  /**
123
 
   * Creates EdgeNGramTokenizer that can generate n-grams in the sizes of the given range
124
 
   *
125
 
   * @param input {@link Reader} holding the input to be tokenized
126
 
   * @param sideLabel the name of the {@link Side} from which to chop off an n-gram
127
 
   * @param minGram the smallest n-gram to generate
128
 
   * @param maxGram the largest n-gram to generate
129
 
   */
130
 
  public EdgeNGramTokenizer(Reader input, String sideLabel, int minGram, int maxGram) {
131
 
    this(input, Side.getSide(sideLabel), minGram, maxGram);
132
 
  }
133
 
 
134
 
  /**
135
 
   * Creates EdgeNGramTokenizer that can generate n-grams in the sizes of the given range
136
 
   *
137
 
   * @param source {@link AttributeSource} to use
138
 
   * @param input {@link Reader} holding the input to be tokenized
139
 
   * @param sideLabel the name of the {@link Side} from which to chop off an n-gram
140
 
   * @param minGram the smallest n-gram to generate
141
 
   * @param maxGram the largest n-gram to generate
142
 
   */
143
 
  public EdgeNGramTokenizer(AttributeSource source, Reader input, String sideLabel, int minGram, int maxGram) {
144
 
    this(source, input, Side.getSide(sideLabel), minGram, maxGram);
145
 
  }
146
 
 
147
 
  /**
148
 
   * Creates EdgeNGramTokenizer that can generate n-grams in the sizes of the given range
149
 
   * 
150
 
   * @param factory {@link org.apache.lucene.util.AttributeSource.AttributeFactory} to use
151
 
   * @param input {@link Reader} holding the input to be tokenized
152
 
   * @param sideLabel the name of the {@link Side} from which to chop off an n-gram
153
 
   * @param minGram the smallest n-gram to generate
154
 
   * @param maxGram the largest n-gram to generate
155
 
   */
156
 
  public EdgeNGramTokenizer(AttributeFactory factory, Reader input, String sideLabel, int minGram, int maxGram) {
157
 
    this(factory, input, Side.getSide(sideLabel), minGram, maxGram);
158
 
  }
159
 
  
160
 
  private void init(Side side, int minGram, int maxGram) {
161
 
    if (side == null) {
162
 
      throw new IllegalArgumentException("sideLabel must be either front or back");
163
 
    }
164
 
 
165
 
    if (minGram < 1) {
166
 
      throw new IllegalArgumentException("minGram must be greater than zero");
167
 
    }
168
 
 
169
 
    if (minGram > maxGram) {
170
 
      throw new IllegalArgumentException("minGram must not be greater than maxGram");
171
 
    }
172
 
 
173
 
    this.minGram = minGram;
174
 
    this.maxGram = maxGram;
175
 
    this.side = side;
176
 
  }
177
 
 
178
 
  /** Returns the next token in the stream, or null at EOS. */
179
 
  @Override
180
 
  public final boolean incrementToken() throws IOException {
181
 
    clearAttributes();
182
 
    // if we are just starting, read the whole input
183
 
    if (!started) {
184
 
      started = true;
185
 
      char[] chars = new char[1024];
186
 
      int charsRead = input.read(chars);
187
 
      inStr = new String(chars, 0, charsRead).trim();  // remove any leading or trailing spaces
188
 
      inLen = inStr.length();
189
 
      gramSize = minGram;
190
 
    }
191
 
 
192
 
    // if the remaining input is too short, we can't generate any n-grams
193
 
    if (gramSize > inLen) {
194
 
      return false;
195
 
    }
196
 
 
197
 
    // if we have hit the end of our n-gram size range, quit
198
 
    if (gramSize > maxGram) {
199
 
      return false;
200
 
    }
201
 
 
202
 
    // grab gramSize chars from front or back
203
 
    int start = side == Side.FRONT ? 0 : inLen - gramSize;
204
 
    int end = start + gramSize;
205
 
    termAtt.setEmpty().append(inStr, start, end);
206
 
    offsetAtt.setOffset(correctOffset(start), correctOffset(end));
207
 
    gramSize++;
208
 
    return true;
209
 
  }
210
 
  
211
 
  @Override
212
 
  public final void end() {
213
 
    // set final offset
214
 
    final int finalOffset = inLen;
215
 
    this.offsetAtt.setOffset(finalOffset, finalOffset);
216
 
  }    
217
 
 
218
 
  @Override
219
 
  public void reset(Reader input) throws IOException {
220
 
    super.reset(input);
221
 
    reset();
222
 
  }
223
 
 
224
 
  @Override
225
 
  public void reset() throws IOException {
226
 
    super.reset();
227
 
    started = false;
228
 
  }
229
 
}