import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;
import org.xml.sax.SAXException;

/**
   An XML parser for item lists
*/
public class ItemListParser
{
   /**
      Constructs a parser that can parse item lists
   */
   public ItemListParser() 
      throws ParserConfigurationException
   {
      DocumentBuilderFactory factory 
         = DocumentBuilderFactory.newInstance();
      builder = factory.newDocumentBuilder();
   }

   /**
      Parses an XML file containing an item list
      @param fileName the name of the file
      @return an array list containing all items in the XML file
   */
   public ArrayList parse(String fileName) 
      throws SAXException, IOException
   {
      File f = new File(fileName);
      Document doc = builder.parse(f);

      // get the <items> root element

      Element root = doc.getDocumentElement(); 
      return getItems(root);
   }

   /**
      Obtains an array list of items from a DOM element
      @param e an <items> element 
      @return an array list of all <item> children of e
   */
   private static ArrayList getItems(Element e)
   {
      ArrayList items = new ArrayList();

      // get the <item> children

      NodeList children = e.getChildNodes();
      for (int i = 0; i < children.getLength(); i++)
      {
         Node childNode = children.item(i);
         if (childNode instanceof Element)
         {
            Element childElement = (Element)childNode;
            if (childElement.getTagName().equals("item"))
            {
               Item c = getItem(childElement);
               items.add(c);
            }
         }
      }
      return items;
   }

   /**
      Obtains an item from a DOM element
      @param e an <item> element 
      @return the item described by the given element
   */
   private static Item getItem(Element e)
   {
      NodeList children = e.getChildNodes();
      Product p = null;
      int quantity = 0;
      for (int j = 0; j < children.getLength(); j++)
      {
         Node childNode = children.item(j);
         if (childNode instanceof Element)
         {
            Element childElement = (Element)childNode;
            String tagName = childElement.getTagName();
            if (tagName.equals("product"))
               p = getProduct(childElement);
            else if (tagName.equals("quantity"))
            {
               Text textNode = (Text)childElement.getFirstChild();  
               String data = textNode.getData();
               quantity = Integer.parseInt(data);
            }
         }
      }
      return new Item(p, quantity);
   }

   /**
      Obtains a product from a DOM element
      @param e a <product> element 
      @return the product described by the given element
   */
   private static Product getProduct(Element e)
   {
      NodeList children = e.getChildNodes();
      String name = "";
      double price = 0;
      for (int j = 0; j < children.getLength(); j++)
      {
         Node childNode = children.item(j);
         if (childNode instanceof Element)
         {
            Element childElement = (Element)childNode;
            String tagName = childElement.getTagName();
            Text textNode = (Text)childElement.getFirstChild();  

            String data = textNode.getData();
            if (tagName.equals("description"))
               name = data;
            else if (tagName.equals("price"))
               price = Double.parseDouble(data);
         }
      }
      return new Product(name, price);
   }

   private DocumentBuilder builder;
}









