/**
 * University of Illinois/NCSA Open Source License
 *
 * Copyright (c) 2001,2002 The Board of Trustees of the University of Illinois
 * All rights reserved.
 *
 * Developed by:  Open Archives Initiative Metadata Harvesting Project
 *                University of Illinois at Urbana-Champaign
 *                http://oai.grainger.uiuc.edu/
 *
 * Permission is hereby granted, free of charge, to any person obtaining
 * a copy of this software and associated documentation files (the
 * "Software"), to deal with the Software without restriction, including
 * without limitation the rights to use, copy, modify, merge, publish,
 * distribute, sublicense, and/or sell copies of the Software, and to
 * permit persons to whom the Software is furnished to do so, subject to
 * the following conditions:
 *
 *  . Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimers.
 *  . Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimers in the
 *    documentation and/or other materials provided with the distribution.
 *  . Neither the names of Open Archives Initiative Metadata Harvesting
 *    Project, University of Illinois at Urbana-Champaign, nor the names of
 *    its contributors may be used to endorse or promote products derived
 *    from this Software without specific prior written permission.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS WITH THE SOFTWARE.
 *
 * DC.Title:          OAISetList
 * 
 * DC.Description:    Class representing a list of OAI Sets
 * 
 * DC.Contributor:    Yuping Tseng, ytseng1@uiuc.edu, University og Illinois at Urbana-Champaign
 * DC.Contributor:    Tom Habing, thabing@uiuc.edu, University of Illinois at Urbana-Champaign
 * 
 * DC.Date.Modified:  Modtime: 4/01/02 11:58a 
 * 
 * DC:Rights:         University of Illinois/NCSA Open Source License
 * 
 * DC.Relation:       For more information see http://oai.grainger.uiuc.edu/
 * DC.Relation:       See http://www.openarchives.org/OAI/openarchivesprotocol.html
 * 
 */
package uiuc.oai;

import javax.xml.transform.*;
import org.w3c.dom.*;
import org.apache.xpath.*;
import org.apache.xpath.objects.*;
import org.apache.xml.utils.*;

/**
 * This class represents a list of Sets, as returned by the ListSets OAI request. This class is similar to a read-only, forward-only 
 *  database cursor. It will automatically handle resumptionTokens and any other flow control used by a repository, such as HTTP 
 *  redirects or retries.
 * 
 * This object is returned by the OAIRepository.ListSets method.
 */ 
public class OAISetList {

  /**
   * Constructs a empty list.
   */
  public OAISetList() {
  }

  /**
   * Returns an OAISet object for the current record in the list.
   */
  public OAISet getCurrentItem() throws OAIException {
    Node node;
    Node node2;
    OAISet s = new OAISet();
    XPath xpath;
    PrefixResolverDefault prefixResolver;
    XPathContext xpathSupport;
    int ctxtNode;
    XObject list;
  
    node = oaiResume.getItem();
  
    if (node != null) {
      try {
        prefixResolver = new PrefixResolverDefault(getOAIRepository().getNamespaceNode());
        xpath = new XPath("oai:setName", null, prefixResolver, XPath.SELECT, null);
        xpathSupport = new XPathContext();
        ctxtNode = xpathSupport.getDTMHandleFromNode(node);   
        list = xpath.execute(xpathSupport, ctxtNode, prefixResolver);
        node2 = list.nodeset().nextNode();
        s.frndSetSetName(node2.getFirstChild().getNodeValue());

        xpath = new XPath("oai:setSpec", null, prefixResolver, XPath.SELECT, null);
        list = xpath.execute(xpathSupport, ctxtNode, prefixResolver);
        node2 = list.nodeset().nextNode();

        xpath = new XPath("oai:setDescription", null, prefixResolver, XPath.SELECT, null);
        list = xpath.execute(xpathSupport, ctxtNode, prefixResolver);
        s.frndSetSetDescription(list.nodelist());
        s.frndSetValid(this.isListValid());
      } catch (TransformerException te) {
        throw new OAIException(OAIException.CRITICAL_ERR, te.getMessage());
      }
    } else {
      s = null;
    }
    return s;
  }

  /**
   * Return the index of the current item (0 to CompleteListSize-1)
   */
  public int getCurrentIndex() throws OAIException {
    return oaiResume.getIndex();
  }  
        
  /**
   * Return the number of items in the list (-1 if unknown)
   */
  public int getCompleteSize() throws OAIException {
    return oaiResume.getCompleteSize();
  }

 /**
  * Returns true if the record list appears to be valid (well-formed, and if the Validation if Very Strict also valid according 
  *  to the XML Schemas); if the Validation is Loose and the record is not well-formed, false is returned. 
  */
  public boolean isListValid() {
    return oaiResume.isResponseValid();
  }

  /** 
   * Returns true if there are more records in the record list; else false. 
   */
  public boolean moreItems() throws OAIException {
    return oaiResume.more();
  }

  /**
   * Moves the cursor location to the next record in the list. 
   */
  public void moveNext() throws OAIException {
    oaiResume.moveNext();
  }

  /** 
   * Returns the OAIRepository object from which this list was created.
   */
  public OAIRepository getOAIRepository() {
    return oaiResume.getRepository();
  }

  /**
   * This will reset the entire list to the beginning, redoing the query from scratch.
   */
  public void requery() throws OAIException {
    oaiResume.requery();
  }

  protected void frndSetOAIResumptionStream(OAIResumptionStream rs) {
    oaiResume = rs;
  }

  private OAIResumptionStream oaiResume;
}
