/*
Copyright (C) 2000-2010  Ministere de la culture et de la communication (France), AJLSM
See LICENCE file
*/
package fr.gouv.culture.sdx.search.lucene.analysis;

import java.io.Reader;

import org.apache.avalon.framework.configuration.Configuration;
import org.apache.avalon.framework.configuration.ConfigurationException;
import org.apache.lucene.analysis.LowerCaseFilter;
import org.apache.lucene.analysis.StopFilter;
import org.apache.lucene.analysis.TokenStream;

import fr.gouv.culture.sdx.search.lucene.analysis.filter.FrenchStandardFilter;
import fr.gouv.culture.sdx.search.lucene.analysis.filter.ISOLatin1AccentFilter;
import fr.gouv.culture.sdx.search.lucene.analysis.tokenizer.LetterOrDigitTokenizer;

/**
 * An analyzer for french language.
 *
 * <p>
 * This analyzers performs these tasks :
 * <ul>
 * <li>all letters are converted to lower case
 * <li>stop words are removed, the list of words removed can come from a configuration file or use a default one
 * <li>accents from ISO-8859-1 can be removed
 * </ul>
 * <p>
 * The possible configurations of this analyzer are :
 * <ul>
 * <li>A list of stop words can be given in the configuration file, a default list is hardcoded.
 * <li>Accented characters are converted to their unaccented form by default, but this can be override with the keepAccent attribute
 * </ul>
 */
public class Analyzer_fr extends DefaultAnalyzer {

	/**
	 * @see fr.gouv.culture.sdx.search.lucene.analysis.AbstractAnalyzer#getAnalyserType()
	 */
	protected String getAnalyzerType() {
		return Analyzer_fr.ANALYZER_TYPE;
	}
	protected final static String ANALYZER_TYPE="Analyzer_fr";

    /** If true, we keep the accents. */
    private boolean keepAccents = false;

    /** The attribute name for keeping accents or not. */
    private static final String KEEP_ACCENTS_ATTRIBUTE = "keepAccents";

    /**
     * Configures this analyzer.
     */
    public void configure(Configuration configuration) throws ConfigurationException {
        // The super class will handle the stop words
        super.configure(configuration);

        // Now we check for accents
        if (configuration != null) keepAccents = configuration.getAttributeAsBoolean(KEEP_ACCENTS_ATTRIBUTE, false);
    }

    /**
     * Builds a chain for filtering words.
     * <p>
     * The chain is this one :
     * <ul>
     * <li>{@link LetterOrDigitTokenizer}
     * <li>{@linkplain FrenchStandardFilter French standard filter}
     * <li>{@linkplain org.apache.lucene.analysis.LowerCaseFilter Lucene's lower case filter}
     * <li>{@linkplain org.apache.lucene.analysis.StopFilter Stop words filter (by default, can be overridden)}
     * <li>{@linkplain ISOLatin1AccentFilter ISOLatin1 accent remover (by default, can be overridden)}
     * </ul>
     */
    public final TokenStream tokenStream(String fieldName, Reader reader) {

        // The token stream that will be returned.
        TokenStream result;

        // Builds the chain...
        result = new LetterOrDigitTokenizer(reader);

        FrenchStandardFilter fsf = new FrenchStandardFilter(result);
        fsf.enableLogging(logger);
        fsf.setUp(result);

        result = fsf;

        result = new LowerCaseFilter(result);
        // Les mots vides avant de supprimer les accents
        if (stopTable != null) result = new StopFilter(result, stopTable);
        if (!keepAccents) {
        	// MAJ Lucene 2.1.0
            //ISOLatin1AccentFilter ilf = new ISOLatin1AccentFilter();
        	ISOLatin1AccentFilter ilf = new ISOLatin1AccentFilter(result);
            ilf.enableLogging(logger);
            ilf.setUp(result);
            result = ilf;

        }

        // And returns the end of the chain
        return result;
    }
}
