PyLucene 3.4.0-1 import
[pylucene.git] / lucene-java-3.4.0 / lucene / contrib / analyzers / common / src / java / org / apache / lucene / analysis / ar / ArabicAnalyzer.java
1 package org.apache.lucene.analysis.ar;
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.File;
21 import java.io.IOException;
22 import java.io.Reader;
23 import java.util.Hashtable;
24 import java.util.Set;
25
26 import org.apache.lucene.analysis.Analyzer;
27 import org.apache.lucene.analysis.LowerCaseFilter;
28 import org.apache.lucene.analysis.CharArraySet;
29 import org.apache.lucene.analysis.KeywordMarkerFilter;
30 import org.apache.lucene.analysis.StopFilter;
31 import org.apache.lucene.analysis.StopwordAnalyzerBase;
32 import org.apache.lucene.analysis.TokenStream;
33 import org.apache.lucene.analysis.Tokenizer;
34 import org.apache.lucene.analysis.WordlistLoader;
35 import org.apache.lucene.analysis.standard.StandardTokenizer;
36 import org.apache.lucene.util.Version;
37
38 /**
39  * {@link Analyzer} for Arabic. 
40  * <p>
41  * This analyzer implements light-stemming as specified by:
42  * <i>
43  * Light Stemming for Arabic Information Retrieval
44  * </i>    
45  * http://www.mtholyoke.edu/~lballest/Pubs/arab_stem05.pdf
46  * <p>
47  * The analysis package contains three primary components:
48  * <ul>
49  *  <li>{@link ArabicNormalizationFilter}: Arabic orthographic normalization.
50  *  <li>{@link ArabicStemFilter}: Arabic light stemming
51  *  <li>Arabic stop words file: a set of default Arabic stop words.
52  * </ul>
53  * 
54  */
55 public final class ArabicAnalyzer extends StopwordAnalyzerBase {
56
57   /**
58    * File containing default Arabic stopwords.
59    * 
60    * Default stopword list is from http://members.unine.ch/jacques.savoy/clef/index.html
61    * The stopword list is BSD-Licensed.
62    */
63   public final static String DEFAULT_STOPWORD_FILE = "stopwords.txt";
64
65   /**
66    * The comment character in the stopwords file.  All lines prefixed with this will be ignored
67    * @deprecated use {@link WordlistLoader#getWordSet(File, String)} directly  
68    */
69   // TODO make this private 
70   @Deprecated
71   public static final String STOPWORDS_COMMENT = "#";
72   
73   /**
74    * Returns an unmodifiable instance of the default stop-words set.
75    * @return an unmodifiable instance of the default stop-words set.
76    */
77   public static Set<?> getDefaultStopSet(){
78     return DefaultSetHolder.DEFAULT_STOP_SET;
79   }
80   
81   /**
82    * Atomically loads the DEFAULT_STOP_SET in a lazy fashion once the outer class 
83    * accesses the static final set the first time.;
84    */
85   private static class DefaultSetHolder {
86     static final Set<?> DEFAULT_STOP_SET;
87
88     static {
89       try {
90         DEFAULT_STOP_SET = loadStopwordSet(false, ArabicAnalyzer.class, DEFAULT_STOPWORD_FILE, STOPWORDS_COMMENT);
91       } catch (IOException ex) {
92         // default set should always be present as it is part of the
93         // distribution (JAR)
94         throw new RuntimeException("Unable to load default stopword set");
95       }
96     }
97   }
98   
99   private final Set<?> stemExclusionSet;
100
101   /**
102    * Builds an analyzer with the default stop words: {@link #DEFAULT_STOPWORD_FILE}.
103    */
104   public ArabicAnalyzer(Version matchVersion) {
105     this(matchVersion, DefaultSetHolder.DEFAULT_STOP_SET);
106   }
107   
108   /**
109    * Builds an analyzer with the given stop words
110    * 
111    * @param matchVersion
112    *          lucene compatibility version
113    * @param stopwords
114    *          a stopword set
115    */
116   public ArabicAnalyzer(Version matchVersion, Set<?> stopwords){
117     this(matchVersion, stopwords, CharArraySet.EMPTY_SET);
118   }
119
120   /**
121    * Builds an analyzer with the given stop word. If a none-empty stem exclusion set is
122    * provided this analyzer will add a {@link KeywordMarkerFilter} before
123    * {@link ArabicStemFilter}.
124    * 
125    * @param matchVersion
126    *          lucene compatibility version
127    * @param stopwords
128    *          a stopword set
129    * @param stemExclusionSet
130    *          a set of terms not to be stemmed
131    */
132   public ArabicAnalyzer(Version matchVersion, Set<?> stopwords, Set<?> stemExclusionSet){
133     super(matchVersion, stopwords);
134     this.stemExclusionSet = CharArraySet.unmodifiableSet(CharArraySet.copy(
135         matchVersion, stemExclusionSet));
136   }
137
138   /**
139    * Builds an analyzer with the given stop words.
140    * @deprecated use {@link #ArabicAnalyzer(Version, Set)} instead
141    */
142   @Deprecated
143   public ArabicAnalyzer( Version matchVersion, String... stopwords ) {
144     this(matchVersion, StopFilter.makeStopSet(matchVersion, stopwords ));
145   }
146
147   /**
148    * Builds an analyzer with the given stop words.
149    * @deprecated use {@link #ArabicAnalyzer(Version, Set)} instead
150    */
151   @Deprecated
152   public ArabicAnalyzer( Version matchVersion, Hashtable<?,?> stopwords ) {
153     this(matchVersion, stopwords.keySet());
154   }
155
156   /**
157    * Builds an analyzer with the given stop words.  Lines can be commented out using {@link #STOPWORDS_COMMENT}
158    * @deprecated use {@link #ArabicAnalyzer(Version, Set)} instead
159    */
160   @Deprecated
161   public ArabicAnalyzer( Version matchVersion, File stopwords ) throws IOException {
162     this(matchVersion, WordlistLoader.getWordSet( stopwords, STOPWORDS_COMMENT));
163   }
164
165   /**
166    * Creates
167    * {@link org.apache.lucene.analysis.ReusableAnalyzerBase.TokenStreamComponents}
168    * used to tokenize all the text in the provided {@link Reader}.
169    * 
170    * @return {@link org.apache.lucene.analysis.ReusableAnalyzerBase.TokenStreamComponents}
171    *         built from an {@link StandardTokenizer} filtered with
172    *         {@link LowerCaseFilter}, {@link StopFilter},
173    *         {@link ArabicNormalizationFilter}, {@link KeywordMarkerFilter}
174    *         if a stem exclusion set is provided and {@link ArabicStemFilter}.
175    */
176   @Override
177   protected TokenStreamComponents createComponents(String fieldName,
178       Reader reader) {
179     final Tokenizer source = matchVersion.onOrAfter(Version.LUCENE_31) ? 
180         new StandardTokenizer(matchVersion, reader) : new ArabicLetterTokenizer(matchVersion, reader);
181     TokenStream result = new LowerCaseFilter(matchVersion, source);
182     // the order here is important: the stopword list is not normalized!
183     result = new StopFilter( matchVersion, result, stopwords);
184     // TODO maybe we should make ArabicNormalization filter also KeywordAttribute aware?!
185     result = new ArabicNormalizationFilter(result);
186     if(!stemExclusionSet.isEmpty()) {
187       result = new KeywordMarkerFilter(result, stemExclusionSet);
188     }
189     return new TokenStreamComponents(source, new ArabicStemFilter(result));
190   }
191 }
192