001 /* 002 * TemplateParser.java 003 * 004 * Developed for the "Rethinking CS101" project. See http://www.cs101.org, the 005 * CS101 homepage or email las@olin.edu. 006 * 007 * Please do not redistribute without obtaining permission. 008 * Created on January 8, 2004, 2:53 PM 009 */ 010 011 package nodenet; 012 013 import org.xml.sax.XMLReader; 014 import org.xml.sax.Attributes; 015 import org.xml.sax.InputSource; 016 import org.xml.sax.SAXException; 017 import org.xml.sax.helpers.DefaultHandler; 018 019 import java.io.FileNotFoundException; 020 import java.io.FileReader; 021 import java.io.IOException; 022 023 import java.util.List; 024 import java.util.Vector; 025 import java.util.HashMap; 026 import java.util.ArrayList; 027 028 import javax.xml.parsers.SAXParser; 029 import javax.xml.parsers.SAXParserFactory; 030 import javax.xml.parsers.ParserConfigurationException; 031 032 import cs101.xml.SimpleErrorHandler; 033 034 035 036 037 /** 038 * A class for reading a template file and converting it into a List 039 * of {@link NodeNetElement}. 040 * 041 * @author Patrick G. Heck, gus.heck@olin.edu 042 * @version $Id: TemplateParser.java,v 1.4 2004/01/14 21:43:17 gus Exp $ 043 */ 044 public class TemplateParser { 045 046 private NodeBehaviorProvider provider; 047 private List elements; 048 private List warnings; 049 050 /** Creates a new instance of TemplateParser */ 051 public TemplateParser(NodeBehaviorProvider provider) { 052 this.provider = provider; 053 } 054 055 public List parse(String fName) throws FileNotFoundException, 056 ParserConfigurationException, SAXException { 057 this.warnings = new ArrayList(); 058 059 elements = new Vector(); 060 FileReader fr = new FileReader(fName); 061 InputSource is = new InputSource(fr); 062 is.setSystemId(DTDResolver.KLUDGE); 063 064 SAXParserFactory spf = SAXParserFactory.newInstance(); 065 spf.setValidating(true); 066 SAXParser parser = spf.newSAXParser(); 067 XMLReader xRead = parser.getXMLReader(); 068 xRead.setErrorHandler(new SimpleErrorHandler()); 069 xRead.setContentHandler(new myContentHandler()); 070 xRead.setEntityResolver(new DTDResolver()); 071 try { 072 xRead.parse(is); 073 fr.close(); 074 } catch (IOException ioe) { 075 throw new SAXException(ioe); 076 } 077 078 return elements; 079 } 080 081 /** 082 * Getter for property warnings. 083 * 084 * @return Value of property warnings. 085 */ 086 public java.util.List getWarnings() { 087 return warnings; 088 } 089 090 /** 091 * Add a message to the warnings. 092 */ 093 094 private void warn(String msg) { 095 warnings.add(msg); 096 } 097 098 private class myContentHandler extends DefaultHandler { 099 100 /** 101 * keep track of what ID was assigned to the node created 102 * and relate it to the ID in the file with this map. 103 */ 104 HashMap nodeMap = new HashMap(); 105 106 public void startElement(String uri, String localName, 107 String qname, Attributes attributes) throws SAXException { 108 109 if ("node".equals(qname)) { 110 String idVal = attributes.getValue("id"); 111 112 String nbVal = attributes.getValue("type"); 113 String xVal = attributes.getValue("x"); 114 String yVal = attributes.getValue("y"); 115 String showVal = attributes.getValue("showName"); 116 String enabledVal = attributes.getValue("enabled"); 117 118 String name = attributes.getValue("name"); // no conversion 119 120 idVal = idVal.replaceFirst("node", ""); 121 Integer id = new Integer(idVal); 122 int x = new Integer(xVal).intValue(); 123 int y = new Integer(yVal).intValue(); 124 boolean show = new Boolean(showVal).booleanValue(); 125 boolean enabled = new Boolean(enabledVal).booleanValue(); 126 127 Class nb = null; 128 if ("Generator".equals(nbVal)) { 129 nb = GeneratorNodeBehavior.class; 130 } 131 132 if ("Terminator".equals(nbVal)) { 133 nb = TerminatorNodeBehavior.class; 134 } 135 136 if (nb == null) { 137 nbVal = nbVal.replaceFirst("Behavior", ""); 138 int n = new Integer(nbVal).intValue(); 139 int numBehaviors = provider.getNodeBehaviors().length; 140 if (n >= numBehaviors) { 141 Class substitution = TemplateParser. 142 this.provider.getNodeBehaviors()[0]; 143 TemplateParser.this.warn( "Template has more node " + 144 "types than you have loaded.\n" + substitution.getName() + 145 " has been substituted for the missing node type(s)."); 146 nb = substitution; 147 } else { 148 nb = provider.getNodeBehaviors()[n]; 149 } 150 } 151 152 Node n = new Node(nb, x, y, name, show, enabled); 153 nodeMap.put(id, n); 154 TemplateParser.this.elements.add(n); 155 } 156 157 if ("channel".equals(qname)) { 158 String startVal = attributes.getValue("start"); 159 String endVal = attributes.getValue("end"); 160 String latencyVal = attributes.getValue("latency"); 161 String capacityVal = attributes.getValue("capacity"); 162 String enabledVal = attributes.getValue("enabled"); 163 164 int latency = new Integer(latencyVal).intValue(); 165 int capacity = new Integer(capacityVal).intValue(); 166 boolean enabled = new Boolean(enabledVal).booleanValue(); 167 168 startVal = startVal.replaceFirst("node", ""); 169 Integer startID = new Integer(startVal); 170 Node start = (Node) nodeMap.get(startID); 171 172 endVal = endVal.replaceFirst("node", ""); 173 Integer endID = new Integer(endVal); 174 Node end = (Node) nodeMap.get(endID); 175 176 Channel chan = null; 177 try { 178 chan = new Channel(start, end, enabled, 179 latency, capacity); 180 } catch (SameNodeException sne) { 181 throw new SAXException(sne); 182 } 183 TemplateParser.this.elements.add(chan); 184 } 185 186 } 187 } 188 }