001package edu.pdx.cs410J.family; 002 003import java.io.*; 004import java.net.URL; 005import java.util.*; 006import org.xml.sax.*; 007import org.w3c.dom.*; 008 009/** 010 * This class contains fields and methods that are useful when dealing 011 * with XML data. 012 */ 013class XmlHelper implements EntityResolver, ErrorHandler { 014 015 /** The System ID for the Family Tree DTD */ 016 protected static final String systemID = 017 "http://www.cs.pdx.edu/~whitlock/dtds/familytree.dtd"; 018 019 /** The Public ID for the Family Tree DTD */ 020 protected static final String publicID = 021 "-//Portland State University//DTD CS410J Family Tree//EN"; 022 023 //////////////////// EntityResolver Methods ////////////////// 024 025 /** 026 * Attempt to resolve the external entity (such as a DTD) described 027 * by the given public and system ID. The external entity is 028 * returned as a <code>InputSource</code> 029 */ 030 public InputSource resolveEntity (String publicId, String systemId) 031 throws SAXException, IOException { 032 033 if (publicId != null && publicId.equals(XmlHelper.publicID)) { 034 // We're resolving the external entity for the Family Tree's 035 // DTD. Check to see if its in the jar file. This way we don't 036 // need to go all the way to the website to find the DTD. 037 String location = "/edu/pdx/cs410J/family/familytree.dtd"; 038 InputStream stream = 039 this.getClass().getResourceAsStream(location); 040 if (stream != null) { 041 return new InputSource(stream); 042 } 043 } 044 045 // Try to access the DTD using the URL 046 try { 047 URL url = new URL(systemId); 048 InputStream stream = url.openStream(); 049 return new InputSource(stream); 050 051 } catch (Exception ex) { 052 return null; 053 } 054 } 055 056 ////////////////// ErrorHandler Methods //////////////////////// 057 058 public void warning(SAXParseException ex) throws SAXException { 059 String s = "Warning while parsing XML (" + ex.getLineNumber() + 060 ":" + ex.getColumnNumber() + "): " + ex.getMessage(); 061 System.err.println(s); 062 } 063 064 public void error(SAXParseException ex) throws SAXException { 065 String s = "Error while parsing XML (" + ex.getLineNumber() + 066 ":" + ex.getColumnNumber() + "): " + ex.getMessage(); 067 throw new SAXException(s); 068 } 069 070 public void fatalError(SAXParseException ex) throws SAXException { 071 String s = "Fatal error while parsing XML (" + ex.getLineNumber() 072 + ":" + ex.getColumnNumber() + "): " + ex.getMessage(); 073 throw new SAXException(s); 074 } 075 076 /////////////////// Other Helper Methods /////////////////////// 077 078 /** 079 * Extracts a bunch of notes from an <code>Element</code> 080 */ 081 protected static List<String> extractNotesFrom(Element element) { 082 List<String> list = new ArrayList<String>(); 083 084 NodeList children = element.getChildNodes(); 085 for (int i = 0; i < children.getLength(); i++) { 086 Node node = children.item(i); 087 if (!(node instanceof Element)) { 088 continue; 089 } 090 091 Element child = (Element) node; 092 if (child.getTagName().equals("note")) { 093 list.add(extractTextFrom(child)); 094 } 095 } 096 097 return list; 098 } 099 100 /** 101 * Extracts the text from an <code>Element</code>. 102 */ 103 protected static String extractTextFrom(Element element) { 104 Text text = (Text) element.getFirstChild(); 105 return (text == null ? "" : text.getData()); 106 } 107 108}