/*
 * 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.index.XML;



import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.xpath.XPath;

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

/**
 * Classe se basant sur JDOM et XPATH pour indexer des noeuds de documents XML.
 * <br/><br/>
 * Class based on JDOM and XPATH for indexing nodes in XML documents.
 * @author Rida Benjelloun (rida.benjelloun@bibl.ulaval.ca)
 */
public class XmlNodeIndexer
    extends XmlFileIndexer {

  /**
   * Méthode spécifique à l'indexation par noeuds. Elle retourne une liste de
   * documents Lucene. Actuellement cette méthode est uniquement utilisée pour
   * stocker des noeuds d'un même document XML dans plusieurs documents Lucene.
       * Elle prend comme arguments le fichier à indexer et le fichier de configuration
   * de Lius.
   * <br/><br/>
   * Method specific for indexing nodes. It returns a list of Lucene documents.
       * Actually, the method is only used to save nodes of the same XML document in
       * many Lucene documents. Its parameters are the XML file to index and the Lius
   * configuration file.
   */
  public List createLuceneDocForEachNodeOfDocument(String xmlFile,
      String liusXmlConfigFilePath) {

    LiusConfig lc = LiusConfigBuilder.getSingletonInstance().getLiusConfig(
        liusXmlConfigFilePath);
    HashMap nodesAndLuceneFields = lc.getXmlNodesFields();
    List listOfLuceneDocuments = createLuceneDocForEachNodeOfDocument(xmlFile,
        nodesAndLuceneFields);
    return listOfLuceneDocuments;
  }

  /** Méthode spécifique à l'indexation par noeuds. Elle retourne une liste de
   * documents lucene. Actuellement cette méthode est uniquement utilisée pour
   * stocker des noeuds d'un même document XML dans plusieurs documents Lucene.
       * Elle prend comme arguments le fichier à indexer et le fichier de configuration
   * de Lius sous forme d'un objet de type LiusConfig.
   * <br/><br/>
   * Method specific for indexing nodes. It returns a list of Lucene documents.
       * Actually, the method is only used to save nodes of the same XML document in
       * many Lucene documents. Its parameters are the XML file to index and the Lius
   * configuration file as a LiusConfig object.
   */
  public List createLuceneDocForEachNodeOfDocument(String xmlFile,
      LiusConfig lc) {
    HashMap nodesAndLuceneFields = lc.getXmlNodesFields();
    List listOfLuceneDocuments = createLuceneDocForEachNodeOfDocument(xmlFile,
        nodesAndLuceneFields);
    return listOfLuceneDocuments;
  }

  /**
   * Méthode spécifique à l'indexation par noeuds. Elle retourne une liste de
   * documents Lucene. Actuellement cette méthode est uniquement utilisée pour
   * stocker des noeuds d'un même document XML dans plusieurs documents Lucene.
   * Elle prend comme arguments le fichier à indexer et un HashMap dont la clé
       * est l'expression XPath pour sélectionner le noeud à placer dans le document
       * Lucene, et la valeur une collection d'objets de type LiusFields, permettant
   * de spécifier les champs etc.
   * <br/><br/>
   * Method specific for indexing nodes. It returns a list of Lucene documents.
       * Actually, the method is only used to save nodes of the same XML document in
   * many Lucene documents. Its parameters are the XML file to index, a HashMap
   * which key is an XPath expression to select the node to place in the Lucene
   * document and the value is a collection of LiusField objects, permitting to
   * specify fields etc.
   */
  public List createLuceneDocForEachNodeOfDocument(String fileToIndex,
      HashMap nodesAndLuceneFields) {
    List listOfLuceneDocuments = new ArrayList();
    XmlFileIndexer xi = new XmlFileIndexer();
    org.jdom.Document xmlDoc = (org.jdom.Document) parse(fileToIndex);
    try {
      Set s = nodesAndLuceneFields.keySet();
      Object[] a = s.toArray();
      for (int i = 0; i < a.length; i++) {
        String XpathNode = (String) a[i];
        System.out.println(XpathNode);
        List ls = XPath.selectNodes(xmlDoc, XpathNode);
        Iterator it = ls.iterator();
        while (it.hasNext()) {
          Element elem = (Element) it.next();
          xi.setFileName(fileToIndex);
          org.apache.lucene.document.Document luceneDoc =
              xi.storeNodeInLuceneDocument(elem,
                                           (Collection) nodesAndLuceneFields.
                                           get(
              XpathNode));
          listOfLuceneDocuments.add(luceneDoc);
        }
      }
    }
    catch (JDOMException e) {
      System.out.println(e.getMessage());
    }
    return listOfLuceneDocuments;
  }

}