package com.oreilly.jent.xml;

/**
 * In general, you may use the code in this book in your programs and 
 * documentation. You do not need to contact us for permission unless 
 * you're reproducing a significant portion of the code. For example, 
 * writing a program that uses several chunks of code from this book does 
 * not require permission. Selling or distributing a CD-ROM of examples 
 * from O'Reilly books does require permission. Answering a question by 
 * citing this book and quoting example code does not require permission. 
 * Incorporating a significant amount of example code from this book into 
 * your product's documentation does require permission.
 * 
 * We appreciate, but do not require, attribution. An attribution usually 
 * includes the title, author, publisher, and ISBN. For example: 
 * 
 *   "Java Enterprise in a Nutshell, Third Edition, 
 *    by Jim Farley and William Crawford 
 *    with Prakash Malani, John G. Norman, and Justin Gehtland. 
 *    Copyright 2006 O'Reilly Media, Inc., 0-596-10142-2."
 *  
 *  If you feel your use of code examples falls outside fair use or the 
 *  permission given above, feel free to contact us at 
 *  permissions@oreilly.com.
 */

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.ErrorHandler;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;
import org.xml.sax.XMLReader;

public class OrderHandler extends org.xml.sax.helpers.DefaultHandler {
  
  public static void main(String[] args) {
    SAXParserFactory spf = SAXParserFactory.newInstance();
    spf.setValidating(true); //request a validating parser
    
    XMLReader xmlReader = null;
    try {
      SAXParser saxParser = spf.newSAXParser();
      /* We need an XMLReader to use an ErrorHandler
         We could just pass the DataHandler to the parser if we wanted
         to use the default error handler. */
      xmlReader = saxParser.getXMLReader();
      xmlReader.setContentHandler(new OrderHandler());
      xmlReader.setErrorHandler(new OrderErrorHandler());
      xmlReader.parse("orders.xml");
    } 
    catch (Exception e) {
      e.printStackTrace();
    }
  }
  
  // The startDocument() method is called at the beginning of parsing
  public void startDocument() throws SAXException {
    System.out.println("Incoming Orders:");
  }
  
  // The startElement() method is called at the start of each element
  public void startElement(String namespaceURI, String localName,
                           String rawName, Attributes atts)
  throws SAXException {
    if(localName.equals("order")) {
      System.out.print("\nNew Order Number " + atts.getValue("idnumber") +
                       " for Customer Number " + atts.getValue("custno"));
    } 
    else if (localName.equals("item")) {
      System.out.print("\nLine Item: " + atts.getValue("idnumber") + " (Qty " +
                       atts.getValue("quantity") + ")");
    } 
    else if (localName.equals("shippingaddr")) {
      System.out.println("\nShip by " + atts.getValue("method") + " to:");
    } 
    else if (localName.equals("handling")) {
      System.out.print("\n\tHandling Instructions: ");
    }
  }
  
  // Print Characters within a tag
  // This will print the contents of the <shippingaddr> and <handling> tags
  // There is no guarantee that all characters will be delivered in a
  // single call
  
  public void characters(char[] ch, int start, int length)
  throws SAXException {
    System.out.print(new String(ch, start, length));
  }
  
  /* A custom error handling class, although DefaultHandler implements both
     interfaces. Here we just throw the exception back to the user.*/
  private static class OrderErrorHandler implements ErrorHandler {
    
    public void error(SAXParseException spe) throws SAXException {
      throw new SAXException(spe);
    }
    
    public void warning(SAXParseException spe) throws SAXException {
      System.out.println("\nParse Warning: " + spe.getMessage());
    }
    
    public void fatalError(SAXParseException spe) throws SAXException {
      throw new SAXException(spe);
    }
  }
}
