001// XmlApp.java: base class for Æfred demos.
002// NO WARRANTY! See README, and copyright below.
003// $Id$
004// Modified 11/8/98 to add package statement.
005package com.microstar.xml.demo;
006
007import java.net.MalformedURLException;
008import java.net.URL;
009
010import com.microstar.xml.XmlHandler;
011import com.microstar.xml.XmlParser;
012
013/**
014 * Base class for Ælfred demonstration applications.
015 * <p>This class fills in the basic interface, and provides
016 * an I/O infrastructure for simple applications and applets.
017 * @author Copyright (c) 1997, 1998 by Microstar Software Ltd.;
018 * @author written by David Megginson &lt;dmeggins@microstar.com&gt;
019 * @version 1.1
020 * @since Ptolemy II 0.2
021 * @see com.microstar.xml.XmlParser
022 * @see com.microstar.xml.XmlHandler
023 * @see EventDemo
024 * @see TimerDemo
025 * @see DtdDemo
026 * @see StreamDemo
027 */
028public class XmlApp implements XmlHandler {
029    /**
030     * Flag to show whether we're running as an applet or application.
031     */
032    public boolean isApplet = false;
033
034    public XmlParser parser;
035
036    //////////////////////////////////////////////////////////////////////
037    // Implementation of XmlParser interface.
038    //
039    // The following methods provide a full skeleton implementation of the
040    // XmlHandler interface, so that subclasses can override only
041    // the methods they need.
042    //////////////////////////////////////////////////////////////////////
043
044    /**
045     * Resolve an external entity.
046     * <p>This method could generate a new URL by looking up the
047     * public identifier in a hash table, or it could replace the
048     * URL supplied with a different, local one; for now, however,
049     * just return the URL supplied.
050     * @see com.microstar.xml.XmlHandler#resolveEntity
051     */
052    @Override
053    public Object resolveEntity(String publicId, String systemId) {
054        return null;
055    }
056
057    @Override
058    public void startExternalEntity(String systemId) {
059    }
060
061    @Override
062    public void endExternalEntity(String systemId) {
063    }
064
065    /**
066     * Handle the start of the document.
067     * <p>Do nothing for now.  Subclasses can override this method
068     * if they want to take a specific action.
069     * <p>This method will always be called first.
070     * @see com.microstar.xml.XmlHandler#startDocument
071     */
072    @Override
073    public void startDocument() {
074    }
075
076    /**
077     * Handle the end the document.
078     * <p>Do nothing for now.  Subclasses can override this method
079     * if they want to take a specific action.
080     * <p>This method will always be called last.
081     * @see com.microstar.xml.XmlHandler#endDocument
082     */
083    @Override
084    public void endDocument() {
085    }
086
087    /**
088     * Handle a DOCTYPE declaration.
089     * <p>Do nothing for now.  Subclasses can override this method
090     * if they want to take a specific action.
091     * <p>Well-formed XML documents might not have one of these.
092     * <p>The query methods in XmlParser will return useful
093     * values only after this callback.
094     * @see com.microstar.xml.XmlHandler#doctypeDecl
095     */
096    @Override
097    public void doctypeDecl(String name, String pubid, String sysid) {
098    }
099
100    /**
101     * Handle an attribute value specification.
102     * <p>Do nothing for now.  Subclasses can override this method
103     * if they want to take a specific action.
104     * @see com.microstar.xml.XmlHandler#attribute
105     */
106    @Override
107    public void attribute(String name, String value, boolean isSpecified) {
108    }
109
110    /**
111     * Handle the start of an element.
112     * <p>Do nothing for now.  Subclasses can override this method
113     * if they want to take a specific action.
114     * @see com.microstar.xml.XmlHandler#startElement
115     */
116    @Override
117    public void startElement(String name) {
118    }
119
120    /**
121     * Handle the end of an element.
122     * <p>Do nothing for now.  Subclasses can override this method
123     * if they want to take a specific action.
124     * @see com.microstar.xml.XmlHandler#endElement
125     */
126    @Override
127    public void endElement(String name) {
128    }
129
130    /**
131     * Handle character data.
132     * <p>Do nothing for now.  Subclasses can override this method
133     * if they want to take a specific action.
134     * @see com.microstar.xml.XmlHandler#charData
135     */
136    @Override
137    public void charData(char[] ch, int start, int length) {
138    }
139
140    /**
141     * Handle ignorable whitespace.
142     * <p>Do nothing for now.  Subclasses can override this method
143     * if they want to take a specific action.
144     * @see com.microstar.xml.XmlHandler#ignorableWhitespace
145     */
146    @Override
147    public void ignorableWhitespace(char[] ch, int start, int length) {
148    }
149
150    /**
151     * Handle a processing instruction.
152     * <p>Do nothing for now.  Subclasses can override this method
153     * if they want to take a specific action.
154     * @see com.microstar.xml.XmlHandler#processingInstruction
155     */
156    @Override
157    public void processingInstruction(String target, String data) {
158    }
159
160    /**
161     * Handle a parsing error.
162     * <p>By default, print a message and throw an Error.
163     * <p>Subclasses can override this method if they want to do something
164     * different.
165     * @see com.microstar.xml.XmlHandler#error
166     */
167    @Override
168    public void error(String message, String url, int line, int column) {
169        displayText("FATAL ERROR: " + message);
170        displayText("  at " + url + ": line " + line + " column " + column);
171        throw new Error(message);
172    }
173
174    //////////////////////////////////////////////////////////////////////
175    // General utility methods.
176    //////////////////////////////////////////////////////////////////////
177
178    /**
179     * Start a parse in application mode.
180     * <p>Output will go to STDOUT.
181     * @see #displayText(String)
182     * @see com.microstar.xml.XmlParser#parse(String, String, String)
183     */
184    void doParse(String url) throws java.lang.Exception {
185        /* String docURL = */makeAbsoluteURL(url);
186
187        // create the parser
188        parser = new XmlParser();
189        parser.setHandler(this);
190        parser.parse(makeAbsoluteURL(url), null, (String) null);
191    }
192
193    static String makeAbsoluteURL(String url) throws MalformedURLException {
194        URL baseURL;
195
196        String currentDirectory = System.getProperty("user.dir");
197
198        String fileSep = System.getProperty("file.separator");
199        String file = currentDirectory.replace(fileSep.charAt(0), '/') + '/';
200
201        if (file.charAt(0) != '/') {
202            file = "/" + file;
203        }
204
205        baseURL = new URL("file", null, file);
206        return new URL(baseURL, url).toString();
207    }
208
209    /**
210     * Display text on STDOUT or in an applet TextArea.
211     */
212    void displayText(String text) {
213        System.out.println(text);
214    }
215
216    /**
217     * Escape a string for printing.
218     */
219    String escape(char[] ch, int length) {
220        StringBuffer out = new StringBuffer();
221
222        for (int i = 0; i < length; i++) {
223            switch (ch[i]) {
224            case '\\':
225                out.append("\\\\");
226                break;
227
228            case '\n':
229                out.append("\\n");
230                break;
231
232            case '\t':
233                out.append("\\t");
234                break;
235
236            case '\r':
237                out.append("\\r");
238                break;
239
240            case '\f':
241                out.append("\\f");
242                break;
243
244            default:
245                out.append(ch[i]);
246                break;
247            }
248        }
249
250        return out.toString();
251    }
252}
253
254// end of XmlApp.java