001package edu.pdx.cs410J.xml;
002
003import org.w3c.dom.Document;
004import org.w3c.dom.Element;
005import org.w3c.dom.Node;
006import org.w3c.dom.NodeList;
007import org.xml.sax.SAXException;
008
009import javax.xml.parsers.DocumentBuilder;
010import javax.xml.parsers.DocumentBuilderFactory;
011import javax.xml.parsers.ParserConfigurationException;
012import java.io.File;
013import java.io.IOException;
014import java.io.PrintStream;
015import java.util.ArrayList;
016import java.util.Collection;
017
018/**
019 * This class represents a phone book that contains entries for
020 * businesses and residents.  It is constructed from an XML DOM tree.
021 * If we doing this for real, we'd want to be able to construct an
022 * empty <code>PhoneBook</code> and add entries.  But, come on, this
023 * is just an example.
024 */
025public class PhoneBook {
026  private static PrintStream err = System.err;
027
028  private Collection<PhoneBookEntry> entries = new ArrayList<>();
029
030  /**
031   * Creates a <code>PhoneBook</code> from an XML DOM tree.
032   */
033  public PhoneBook(Element root) {
034    // Verify that this is a phonebook XML doc
035    if (!root.getNodeName().equals("phonebook")) {
036      String s = "Not a phonebook: " + root.getNodeName();
037      throw new IllegalArgumentException(s);
038    }
039
040    NodeList entries = root.getChildNodes();
041    for (int i = 0; i < entries.getLength(); i++) {
042      Node node = entries.item(i);
043
044      if (!(node instanceof Element)) {
045        // Ignore other stuff
046        continue;
047      }
048
049      Element entry = (Element) node;
050      switch (entry.getNodeName()) {
051        case "resident":
052          this.entries.add(new Resident(entry));
053          break;
054        case "business":
055          this.entries.add(new Business(entry));
056          break;
057        default:
058          String s = "Unknown entry: " + entry.getNodeName() + " (" +
059            entry.getNodeValue() + ")";
060          throw new IllegalArgumentException(s);
061      }
062    }
063  }
064
065  /**
066   * Test program that takes the name of a XML file from the command
067   * line and attempts to make a <code>PhoneBook</code> out of it.
068   */
069  public static void main(String[] args) {
070    // Parse the XML file to create a DOM tree
071    Document doc = null;
072    try {
073      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
074      factory.setValidating(true);
075
076      DocumentBuilder builder =  factory.newDocumentBuilder();
077      doc = builder.parse(new File(args[0]));
078
079    } catch (ParserConfigurationException ex) {
080      err.println("** " + ex);
081      System.exit(1);
082
083    } catch (SAXException ex) {
084      err.println("** SAXException: " + ex);
085      System.exit(1);
086
087    } catch (IOException ex) {
088      err.println("** IOException: " + ex);
089      System.exit(1);
090    }
091
092    Element root = (Element) doc.getChildNodes().item(1);
093    PhoneBook phonebook = new PhoneBook(root);
094    System.out.println(phonebook);
095  }
096
097  public String toString() {
098    StringBuilder sb = new StringBuilder();
099    sb.append("Phone Book\n\n");
100
101    for (PhoneBookEntry entry : this.entries) {
102      sb.append(entry);
103      sb.append("\n");
104    }
105    
106    return sb.toString();
107  }
108}