/*
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.lucene.analysis.TokenStream;

import fr.gouv.culture.sdx.exception.SDXException;
import fr.gouv.culture.sdx.exception.SDXExceptionCode;
import fr.gouv.culture.sdx.search.lucene.Field;
import fr.gouv.culture.sdx.search.lucene.FieldList;

/**
 * A dispatcher for field specific analyzers.
 *
 * <p>
 * This analyzer knows about specific analyzers for the fields
 * of a document base. Hence, when its tokenStream(fieldName, reader) method
 * is called, it attempts to dispatch the task to a specific analyzer for the
 * given field name.
 */
public class MetaAnalyzer extends AbstractAnalyzer {

	/* (non-Javadoc)
	 * @see fr.gouv.culture.sdx.search.lucene.analysis.AbstractAnalyzer#getAnalyserType()
	 */
	protected String getAnalyzerType() {
		return MetaAnalyzer.ANALYZER_TYPE;
	}
	protected final static String ANALYZER_TYPE="MetaAnalyzer";
	
    /** The fields definition object. */
    private FieldList fields;

    /** The default analzyer to use. */
    private Analyzer defaultAnalyzer;

    /**Creates a MetaAnalyzer
     *
     *  <p>
     * A super.getLog() must be set and then this MetaAnalyzer must be setUp.
     *
     * @see #setUp
     */
    public MetaAnalyzer() {
    }

    /**
     * Builds an analyzer with definitions for fields.
     *
     * @param   fields  The fields and their definitions (cannot be null).
     * @throws SDXException 
     */
    public void setUp(FieldList fields) throws SDXException {

        if (fields == null) throw new SDXException(logger, SDXExceptionCode.ERROR_FIELDS_DEF_NULL, null, null);
        this.fields = fields;
        this.defaultAnalyzer = fields.getAnalyzer();
    }

    /**
     * Tokenizes contents.
     *
     * <p>
     * The tokenizing is never done by this object. Instead, using the provided
     * field name, it will try to get a specific analyzer from the fields definition.
     * If it can't find one, it will use the default analyzer.
     *
     * @param fieldName The field name for tokenization
     * @param reader    The reader
     */
    public TokenStream tokenStream(String fieldName, Reader reader) {
        // If the fieldname is not specified, then we use the default analyzer
        if (fieldName == null) return defaultAnalyzer.tokenStream(fieldName, reader);

        Field f = fields.getField(fieldName);

        // If we have no definition for this field, we use the default analyzer again
        if (f == null) return defaultAnalyzer.tokenStream(fieldName, reader);

        Analyzer theAnalyzer = f.getAnalyzer();

        // If the field's analyzer is not defined, then we use the default analyzer
        if (theAnalyzer == null) return defaultAnalyzer.tokenStream(fieldName, reader);

        // Finally, we can use the specific analyzer for this field
        return theAnalyzer.tokenStream(fieldName, reader);
    }

    /** Returns a the FieldList for this MetaAnalyzer (basically a Hashtable of all the Fields)
     * @return FieldList*/
    //TODO?:is this still necessary, as it exists both in LuceneIndex and MetaAnalyzer?-rbp
    public FieldList getFieldList() {
        return this.fields;
    }
    
    /** Creates a TokenStream which tokenizes all the text in the provided
	 *  Reader. Provided for backward compatibility only.
	 * @deprecated use tokenStream(String, Reader) instead. 
	 * @see fr.gouv.culture.sdx.search.lucene.analysis.Analyzer#tokenStream(java.io.Reader)
	 * @author Malo Pichot, 2007
	 */
	public TokenStream tokenStream(Reader reader) {
		return tokenStream(null, reader);
	}


}
