/**********************************************************
 * ContactReportSAX uses the SAX parser to parse the
 * XML AddressBook file, building up a StringBuffer from each
 * event generated. The program keeps track of first-name, last-name
 * elements nested under PrimaryInfo element (using a boolean flag),
 * and then compares the first-name/last-name combination. If it finds 
 * the first-name/last-name combination, the contents of the buffer are
 * copied to a new buffer, which continues accumulating content now that the
 * flag is true for foundContact.
 *
 * Kelli Wiseth
 * 28-OCT-2004, 26-NOV-2004
 *
 * XML and Web Services class | NDNU 
 *
 ***********************************************************
 */
 
// Java core packages
import java.io.*;

// Java standard extensions
import javax.xml.parsers.*;
import javax.xml.transform.*;

// third-party libraries
import org.xml.sax.*;
import org.xml.sax.helpers.*;

public class ContactReportSAX extends DefaultHandler
  {
 
   String firstNameLookup;
   String lastNameLookup;
   String nodeValue = "";

   public String nickname = "";
   public String first = "";
   public String middle = "";
   public String last = "";
   public String workEmail = "";
   public String homeEmail = "";
   public String alternativeEmail = "";
   public String spouseBirthday = "";
   public String childBirthday = "";
     
   StringBuffer currentContact = new StringBuffer();
   StringBuffer currentElementText = new StringBuffer();
   StringBuffer foundContactText = new StringBuffer();
   boolean foundFirst = false;
   boolean foundLast = false;
   boolean foundContact = false;
   boolean isPrimaryInfo = false;
   boolean outputContact = false;
  
  
   public ContactReportSAX(String firstname, String lastname)
   {
   	firstNameLookup = firstname;
   	lastNameLookup = lastname;
   	
   } 
    

   public void startDocument() 
      {
	  System.out.println("Start processing AddressBook ... ");
	  System.out.println("Searching for contact named " + firstNameLookup + " " + lastNameLookup + "...");
 	  }

   public void startElement(String uri, String localName, String qName, Attributes attributes) 
	  {
	       
 	  if (qName.equals("Contact"))
 	     {
 	     foundContact=false;
 	     currentContact.setLength(0);  //this is the buffer that we'll use to accumulate data
 	     }
 	
 	  else if (qName.equals("PrimaryInfo"))
 	     {
 	     currentElementText.setLength(0);
 	     isPrimaryInfo = true;
 	     }
	     
	  else if (qName.equals("Name") && (isPrimaryInfo))
	     {
	     currentElementText.setLength(0);
	     if (attributes.getLength() > 0)
	        nickname = attributes.getValue(0);
 	     }
            
	  else if (qName.equals("First") && (isPrimaryInfo))
	     {
	     currentElementText.setLength(0);
 	     }
 	  
 	  else if (qName.equals("Middle") && (isPrimaryInfo))
         {
 	     currentElementText.setLength(0);
 	     }
   
      else if (qName.equals("Last") && (isPrimaryInfo))
         {
 	     currentElementText.setLength(0);
 	     } 
 	  
 	  else if (qName.equals("Email") && (foundContact))
         {
         foundContactText.setLength(0);
	     if (attributes.getLength() > 0)
	        alternativeEmail = attributes.getValue(0);
         }
	  else if (qName.equals("WorkEmail") && (foundContact))
	     {
	     foundContactText.setLength(0);
 	     }

	  else if (qName.equals("HomeEmail") && (foundContact))
	     {
	     foundContactText.setLength(0);
 	     }

      else if (qName.equals("sName"))
         {
         foundContactText.setLength(0);
	     if (attributes.getLength() > 0)
	        spouseBirthday = attributes.getValue(0);
         }
      else if (qName.equals("cName"))
         {
         if (attributes.getLength() > 0)
	        childBirthday = attributes.getValue(0);
         currentElementText.setLength(0);
	     }
         
      else
         currentElementText.setLength(0);
	
      
  } //close startElement method

      
  public void characters(char[] ch, int start, int length) 
	    {
      if (foundContact)
         {
         foundContactText.append(ch, start, length);
         }

      else
         currentElementText.append(ch, start, length);
        }
         
  public void endElement(String namespaceURI, String localName, String qName) throws SAXException
		{
      if (qName.equals("Name") && (isPrimaryInfo))
 	      {
 	      currentElementText.setLength(0);
   	      if (nickname!=null)
  	        {
            nickname = nickname;
            }
	      }
 	     
 	  else if (qName.equals("First") && (isPrimaryInfo))
 	       {
		   first = currentElementText.toString().trim();
	       currentContact.append("\n\n" + first + " ");
	       currentElementText.setLength(0);
		     if (first.equalsIgnoreCase(firstNameLookup))
		        foundFirst=true;
  		   }

	  else if (qName.equals("Middle") && (isPrimaryInfo))
	       {
		    middle = currentElementText.toString().trim();
	        currentElementText.setLength(0);
            currentContact.append(middle + " ");
 	       }
 	       
 	  else if (qName.equals("Last") && (isPrimaryInfo))
 	       {
		   last = currentElementText.toString().trim();
           currentContact.append(last + "\n");
	       currentElementText.setLength(0);
 	       
 	       if (last.equalsIgnoreCase(lastNameLookup) && (foundFirst))
		      {
		       foundLast=true;
		       foundContact=true;
		       outputContact=true;
		       currentContact.append("(" + nickname + ")");
 	           foundContactText = foundContactText.append(currentContact.toString().trim());
 	           }
	          else
 	           currentContact.setLength(0);
 	        }// if qName.equals("Last")
 	        
      else if (qName.equals("Email") && (foundContact))
 	      {
 	        if (alternativeEmail!=null)
  	           {
               foundContactText.append(alternativeEmail + "\n");
  	           }
	     // currentElementText.setLength(0);
   	      }
	  else if (qName.equals("WorkEmail") && (foundContact))
	     {
	     workEmail = foundContactText.toString().trim();
	     if (foundContact)
	        foundContactText.append(workEmail + "\n");
   //	     currentContact.append(currentElementText.toString().trim());
	     currentElementText.setLength(0);
	     }

	  else if (qName.equals("HomeEmail") && (foundContact))
	     {
	     homeEmail = currentElementText.toString().trim();
	     if (foundContact)
	        foundContactText.append(homeEmail + "\n");
//	     currentContact.append(currentElementText.toString().trim());
	     currentElementText.setLength(0);
 	     }

 	    else if (qName.equals("PrimaryInfo"))
 	       {
	       isPrimaryInfo = false;
	       currentElementText.setLength(0);
	       }
 
 	
 	   else if (qName.equals("sName"))
          {
          if (spouseBirthday!=null)
             {
             foundContactText.append(spouseBirthday);
             }
          currentElementText.setLength(0);
        
          }	    
	    
	   else if (qName.equals("cName"))
         {
         currentElementText.setLength(0);
	     if (childBirthday!=null)
             foundContactText.append(childBirthday);
         }
 	 	
 		else if (qName.equals("Contact"))
		   {
           if (foundContact) //printout the accumulated foundContactText buffer
              {
              System.out.println(foundContactText.toString().trim());
              }
           currentElementText.setLength(0);
           
           } // close the Contact

        else
 	       {
 	       currentContact.append(currentElementText.toString().trim());
 	       }
 	  } //endElement() 
 	     
  
  public void endDocument() 
	  {
      System.out.println(".........");
	  System.out.println("Processing AddressBook completed.");
      
	  if (!outputContact)
         System.out.println("Sorry, that contact isn't in the AddressBook.");
         	
      }
	  
	  
  public static void main( String args[]) throws Exception
   {
    if ( args.length < 2 ) 
       {
        System.out.print("Syntax: java ContactReportSAX <firstname> <lastname>\n");
        System.out.print("Please enter contact's first name and last name, as in: \n\n");
        System.out.print("              java ContactReportSAX marie sklodowska \n");
        System.exit( 1 );
        }
 
       SAXParserFactory factory = SAXParserFactory.newInstance();
       SAXParser parser = factory.newSAXParser();
       XMLReader xmlReader = parser.getXMLReader();
       xmlReader.setContentHandler(new ContactReportSAX(args[0], args[1]));
       xmlReader.parse("AddressBook.xml");

  }//close main method
   
} //close class ContactReportSAX
