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

« back to all changes in this revision

Viewing changes to solr/core/src/java/org/apache/solr/analysis/HyphenatedWordsFilter.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.solr.analysis;
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 java.io.IOException;
21
 
 
22
 
import org.apache.lucene.analysis.*;
23
 
import org.apache.lucene.analysis.tokenattributes.OffsetAttribute;
24
 
import org.apache.lucene.analysis.tokenattributes.CharTermAttribute;
25
 
 
26
 
/**
27
 
 * When the plain text is extracted from documents, we will often have many words hyphenated and broken into
28
 
 * two lines. This is often the case with documents where narrow text columns are used, such as newsletters.
29
 
 * In order to increase search efficiency, this filter puts hyphenated words broken into two lines back together.
30
 
 * This filter should be used on indexing time only.
31
 
 * Example field definition in schema.xml:
32
 
 * <pre>
33
 
 * &lt;fieldtype name="text" class="solr.TextField" positionIncrementGap="100"&gt;
34
 
 *      &lt;analyzer type="index"&gt;
35
 
 *              &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
36
 
 *      &lt;filter class="solr.SynonymFilterFactory" synonyms="index_synonyms.txt" ignoreCase="true" expand="false"/&gt;
37
 
 *      &lt;filter class="solr.StopFilterFactory" ignoreCase="true"/&gt;
38
 
 *      &lt;filter class="solr.HyphenatedWordsFilterFactory"/&gt;
39
 
 *      &lt;filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="1" catenateNumbers="1" catenateAll="0"/&gt;
40
 
 *      &lt;filter class="solr.LowerCaseFilterFactory"/&gt;
41
 
 *      &lt;filter class="solr.RemoveDuplicatesTokenFilterFactory"/&gt;
42
 
 *  &lt;/analyzer&gt;
43
 
 *  &lt;analyzer type="query"&gt;
44
 
 *      &lt;tokenizer class="solr.WhitespaceTokenizerFactory"/&gt;
45
 
 *      &lt;filter class="solr.SynonymFilterFactory" synonyms="synonyms.txt" ignoreCase="true" expand="true"/&gt;
46
 
 *      &lt;filter class="solr.StopFilterFactory" ignoreCase="true"/&gt;
47
 
 *      &lt;filter class="solr.WordDelimiterFilterFactory" generateWordParts="1" generateNumberParts="1" catenateWords="0" catenateNumbers="0" catenateAll="0"/&gt;
48
 
 *      &lt;filter class="solr.LowerCaseFilterFactory"/&gt;
49
 
 *      &lt;filter class="solr.RemoveDuplicatesTokenFilterFactory"/&gt;
50
 
 *  &lt;/analyzer&gt;
51
 
 * &lt;/fieldtype&gt;
52
 
 * </pre>
53
 
 * 
54
 
 */
55
 
public final class HyphenatedWordsFilter extends TokenFilter {
56
 
 
57
 
  private final CharTermAttribute termAttribute = addAttribute(CharTermAttribute.class);
58
 
  private final OffsetAttribute offsetAttribute = addAttribute(OffsetAttribute.class);
59
 
  
60
 
  private final StringBuilder hyphenated = new StringBuilder();
61
 
  private State savedState;
62
 
  private boolean exhausted = false;
63
 
 
64
 
  /**
65
 
   * Creates a new HyphenatedWordsFilter
66
 
   *
67
 
   * @param in TokenStream that will be filtered
68
 
   */
69
 
  public HyphenatedWordsFilter(TokenStream in) {
70
 
    super(in);
71
 
  }
72
 
 
73
 
  /**
74
 
   * {@inheritDoc}
75
 
   */
76
 
  @Override
77
 
  public boolean incrementToken() throws IOException {
78
 
    while (!exhausted && input.incrementToken()) {
79
 
      char[] term = termAttribute.buffer();
80
 
      int termLength = termAttribute.length();
81
 
      
82
 
      if (termLength > 0 && term[termLength - 1] == '-') {
83
 
        // a hyphenated word
84
 
        // capture the state of the first token only
85
 
        if (savedState == null) {
86
 
          savedState = captureState();
87
 
        }
88
 
        hyphenated.append(term, 0, termLength - 1);
89
 
      } else if (savedState == null) {
90
 
        // not part of a hyphenated word.
91
 
        return true;
92
 
      } else {
93
 
        // the final portion of a hyphenated word
94
 
        hyphenated.append(term, 0, termLength);
95
 
        unhyphenate();
96
 
        return true;
97
 
      }
98
 
    }
99
 
    
100
 
    exhausted = true;
101
 
 
102
 
    if (savedState != null) {
103
 
      // the final term ends with a hyphen
104
 
      // add back the hyphen, for backwards compatibility.
105
 
      hyphenated.append('-');
106
 
      unhyphenate();
107
 
      return true;
108
 
    }
109
 
    
110
 
    return false;
111
 
  }
112
 
 
113
 
  /**
114
 
   * {@inheritDoc}
115
 
   */
116
 
  @Override
117
 
  public void reset() throws IOException {
118
 
    super.reset();
119
 
    hyphenated.setLength(0);
120
 
    savedState = null;
121
 
    exhausted = false;
122
 
  }
123
 
 
124
 
  // ================================================= Helper Methods ================================================
125
 
 
126
 
  /**
127
 
   * Writes the joined unhyphenated term
128
 
   */
129
 
  private void unhyphenate() {
130
 
    int endOffset = offsetAttribute.endOffset();
131
 
    
132
 
    restoreState(savedState);
133
 
    savedState = null;
134
 
    
135
 
    char term[] = termAttribute.buffer();
136
 
    int length = hyphenated.length();
137
 
    if (length > termAttribute.length()) {
138
 
      term = termAttribute.resizeBuffer(length);
139
 
    }
140
 
    
141
 
    hyphenated.getChars(0, length, term, 0);
142
 
    termAttribute.setLength(length);
143
 
    offsetAttribute.setOffset(offsetAttribute.startOffset(), endOffset);
144
 
    hyphenated.setLength(0);
145
 
  }
146
 
}