pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / contrib / analyzers / common / src / java / org / apache / lucene / analysis / fa / PersianAnalyzer.java
1 package org.apache.lucene.analysis.fa;
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.StopFilter;
29 import org.apache.lucene.analysis.StopwordAnalyzerBase;
30 import org.apache.lucene.analysis.CharReader;
31 import org.apache.lucene.analysis.TokenStream;
32 import org.apache.lucene.analysis.Tokenizer;
33 import org.apache.lucene.analysis.WordlistLoader;
34 import org.apache.lucene.analysis.ar.ArabicLetterTokenizer;
35 import org.apache.lucene.analysis.ar.ArabicNormalizationFilter;
36 import org.apache.lucene.analysis.standard.StandardTokenizer;
37
38 import org.apache.lucene.util.IOUtils;
39 import org.apache.lucene.util.Version;
40
41 /**
42  * {@link Analyzer} for Persian.
43  * <p>
44  * This Analyzer uses {@link ArabicLetterTokenizer} which implies tokenizing around
45  * zero-width non-joiner in addition to whitespace. Some persian-specific variant forms (such as farsi
46  * yeh and keheh) are standardized. "Stemming" is accomplished via stopwords.
47  * </p>
48  */
49 public final class PersianAnalyzer extends StopwordAnalyzerBase {
50
51   /**
52    * File containing default Persian stopwords.
53    * 
54    * Default stopword list is from
55    * http://members.unine.ch/jacques.savoy/clef/index.html The stopword list is
56    * BSD-Licensed.
57    * 
58    */
59   public final static String DEFAULT_STOPWORD_FILE = "stopwords.txt";
60
61   /**
62    * The comment character in the stopwords file. All lines prefixed with this
63    * will be ignored
64    */
65   public static final String STOPWORDS_COMMENT = "#";
66   
67   /**
68    * Returns an unmodifiable instance of the default stop-words set.
69    * @return an unmodifiable instance of the default stop-words set.
70    */
71   public static Set<?> getDefaultStopSet(){
72     return DefaultSetHolder.DEFAULT_STOP_SET;
73   }
74   
75   /**
76    * Atomically loads the DEFAULT_STOP_SET in a lazy fashion once the outer class 
77    * accesses the static final set the first time.;
78    */
79   private static class DefaultSetHolder {
80     static final Set<?> DEFAULT_STOP_SET;
81
82     static {
83       try {
84         DEFAULT_STOP_SET = loadStopwordSet(false, PersianAnalyzer.class, DEFAULT_STOPWORD_FILE, STOPWORDS_COMMENT);
85       } catch (IOException ex) {
86         // default set should always be present as it is part of the
87         // distribution (JAR)
88         throw new RuntimeException("Unable to load default stopword set");
89       }
90     }
91   }
92
93   /**
94    * Builds an analyzer with the default stop words:
95    * {@link #DEFAULT_STOPWORD_FILE}.
96    */
97   public PersianAnalyzer(Version matchVersion) {
98     this(matchVersion, DefaultSetHolder.DEFAULT_STOP_SET);
99   }
100   
101   /**
102    * Builds an analyzer with the given stop words 
103    * 
104    * @param matchVersion
105    *          lucene compatibility version
106    * @param stopwords
107    *          a stopword set
108    */
109   public PersianAnalyzer(Version matchVersion, Set<?> stopwords){
110     super(matchVersion, stopwords);
111   }
112
113   /**
114    * Builds an analyzer with the given stop words.
115    * @deprecated use {@link #PersianAnalyzer(Version, Set)} instead
116    */
117   @Deprecated
118   public PersianAnalyzer(Version matchVersion, String... stopwords) {
119     this(matchVersion, StopFilter.makeStopSet(matchVersion, stopwords));
120   }
121
122   /**
123    * Builds an analyzer with the given stop words.
124    * @deprecated use {@link #PersianAnalyzer(Version, Set)} instead
125    */
126   @Deprecated
127   public PersianAnalyzer(Version matchVersion, Hashtable<?, ?> stopwords) {
128     this(matchVersion, stopwords.keySet());
129   }
130
131   /**
132    * Builds an analyzer with the given stop words. Lines can be commented out
133    * using {@link #STOPWORDS_COMMENT}
134    * @deprecated use {@link #PersianAnalyzer(Version, Set)} instead
135    */
136   @Deprecated
137   public PersianAnalyzer(Version matchVersion, File stopwords) throws IOException {
138     this(matchVersion, WordlistLoader.getWordSet(
139         IOUtils.getDecodingReader(stopwords, IOUtils.CHARSET_UTF_8),
140         STOPWORDS_COMMENT, matchVersion));
141   }
142
143   /**
144    * Creates
145    * {@link org.apache.lucene.analysis.ReusableAnalyzerBase.TokenStreamComponents}
146    * used to tokenize all the text in the provided {@link Reader}.
147    * 
148    * @return {@link org.apache.lucene.analysis.ReusableAnalyzerBase.TokenStreamComponents}
149    *         built from a {@link StandardTokenizer} filtered with
150    *         {@link LowerCaseFilter}, {@link ArabicNormalizationFilter},
151    *         {@link PersianNormalizationFilter} and Persian Stop words
152    */
153   @Override
154   protected TokenStreamComponents createComponents(String fieldName,
155       Reader reader) {
156     final Tokenizer source;
157     if (matchVersion.onOrAfter(Version.LUCENE_31)) {
158       source = new StandardTokenizer(matchVersion, reader);
159     } else {
160       source = new ArabicLetterTokenizer(matchVersion, reader);
161     }
162     TokenStream result = new LowerCaseFilter(matchVersion, source);
163     result = new ArabicNormalizationFilter(result);
164     /* additional persian-specific normalization */
165     result = new PersianNormalizationFilter(result);
166     /*
167      * the order here is important: the stopword list is normalized with the
168      * above!
169      */
170     return new TokenStreamComponents(source, new StopFilter(matchVersion, result, stopwords));
171   }
172   
173   /** 
174    * Wraps the Reader with {@link PersianCharFilter}
175    */
176   @Override
177   protected Reader initReader(Reader reader) {
178     return matchVersion.onOrAfter(Version.LUCENE_31) ? 
179        new PersianCharFilter(CharReader.get(reader)) :
180        reader;
181   }
182 }