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