/*
 * LIUS - Lucene Index Update and Search
 * http://sourceforge.net/projects/lius/
 *
 * Copyright (c) 2004, Laval University Library.  All rights reserved.
 *
 * This program is a free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
 */
package ca.ulaval.bibl.lius.Lucene;

import org.apache.lucene.analysis.Analyzer;

import ca.ulaval.bibl.lius.config.LiusConfig;

import java.lang.reflect.Constructor;

/**
 * @author Rida Benjelloun (rida.benjelloun@bibl.ulaval.ca)
 */

public class AnalyzerFactory {

  /**
   * Méthode se basant sur la réflexion. Elle retourne un objet de type
   * "Analyzer" en se basant sur le nom de classe
   * entré par l'utilisateur dans le fichier de configuration.
   * Elle permet également de construire un objet analyzer en utilisant une
   * liste de mots vides, ceci se fait en appelant un constructeur qui se base
   * sur un tableau de mots vides. Le tableau de mots vides est construit à patir
   * du fichier de configuration.
   * <br/><br/>
   * Method that bases itself on reflection. It returns an Analyzer object based
   * from the class name given by the configuration file. Also, the constructed
   * Analyser object can be based on a list of stop words, by calling a constructor
   * based on stop words. The list of stop words is taken form the configuration file.
   */
  public static Analyzer getAnalyzer(LiusConfig xc) {
    if (xc == null)
      System.out.println("xc = null");
    Analyzer an = null;
    try {

      Class classe = Class.forName(xc.getAnalyzer());
      Object analyzerInstance = null;

      if (xc.getStopWord() != null) {
        Constructor[] con = classe.getConstructors();
        for (int i = 0; i < con.length; i++) {
          Class[] conParam = con[i].getParameterTypes();
          if (conParam.length == 0 && an == null) {
            analyzerInstance = classe.newInstance();
            an = (Analyzer) analyzerInstance;
            System.out.println("L'analyseur : " + xc.getAnalyzer() +
                               " ne prend pas de mots vides");
          }
          else {
            for (int j = 0; j < conParam.length; j++) {
              if (conParam[j].getName().equals("[Ljava.lang.String;")) {
                an = (Analyzer) con[i].newInstance(new Object[] {xc.getStopWord()});
              }
            }
          }
        }
      }
      else {

        analyzerInstance = classe.newInstance();
        an = (Analyzer) analyzerInstance;
      }
    }

    catch (ClassNotFoundException e) {
      System.out.println("ClassNotFoundException" + e.getMessage());
    }
    catch (InstantiationException e) {
      System.out.println("La classe est abstract ou est une interface" +
                         e.getMessage());
    }
    catch (IllegalAccessException e) {
      System.out.println("La classe n'est pas accessible" + e.getMessage());
    }
    catch (java.lang.reflect.InvocationTargetException e) {
      System.out.println(" Exception déclenchée si le constructeur invoqué" +
                         e.getMessage());
    }
    catch (IllegalArgumentException e) {
      System.out.println(" Mauvais type de paramètre" + e.getMessage());
    }
    return an;
  }

}