001 /* 002 * DTDResolver.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 * Created on January 8, 2004, 5:24 PM 008 */ 009 010 package nodenet; 011 012 import org.xml.sax.InputSource; 013 import org.xml.sax.EntityResolver; 014 015 import java.io.InputStreamReader; 016 017 /** 018 * This class allows us to validate against a DTD that is found on 019 * the classpath. This is important because otherwise we would need to 020 * deploy the DTD on our website and parsers would look it up there, or the 021 * DTD woud have to be placed in a specific location in the filesystem where 022 * we could find it. In the first case the program would break on computers 023 * not currently connected to the internet, and in the latter case would 024 * impose an unacceptable configuration burden on students and the professors 025 * who guide them. 026 * 027 *<p>The Apache Crimson parser on which the default jvm's rely seems to have 028 * some quirks. One is that the value of sys must be a valid URI (as per 029 * the java.net.URI class with a known scheme) Since this is entirely 030 * irrelevant for the classloader, the KLUDGE constant must be prepended to 031 * the sys string, otherwise crimson will throw exceptions before invoking 032 * this EntityResolver. This appears to violate the spec in the javadoc but 033 * I can't do anything about it. If Java switches to Xerces2 this may 034 * not be neccesary. 035 * 036 * @author Patrick G. Heck, gus.heck@olin.edu 037 * @version $Id: DTDResolver.java,v 1.4 2004/01/15 18:38:38 gus Exp $ 038 */ 039 public class DTDResolver implements org.xml.sax.EntityResolver { 040 041 /** 042 * A dummy string to prepend to the system DTD entity to 043 * workaround a bug in the crimson parser. It is also used to workaround 044 * a problem with InputSource which refuses to use any system resource 045 * unless systemId is set to a valid URI. 046 */ 047 public static final String KLUDGE = "file:///ignoreThisKludge/"; 048 049 /** Creates a new instance of DTDResolver */ 050 public DTDResolver() { 051 } 052 public org.xml.sax.InputSource resolveEntity(String pub, String sys) { 053 // this undoes the name resolution kludge see 054 // SimulationPanel.templateXML for details 055 sys = sys.substring(KLUDGE.length()); 056 InputSource is = null; 057 try { 058 InputStreamReader isr = new InputStreamReader( 059 SimulationPanel.class.getResourceAsStream(sys),"UTF8"); 060 is = new InputSource(isr); 061 } catch (Exception e) { 062 e.printStackTrace(); 063 } 064 return is; // if null default resolution is used 065 } 066 } 067 068