001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package javax.swing.text.html.parser;
018:
019: import java.io.DataInputStream;
020: import java.io.File;
021: import java.io.FileInputStream;
022: import java.io.IOException;
023: import java.io.Reader;
024: import java.io.Serializable;
025: import java.net.URL;
026:
027: import javax.swing.text.html.HTMLEditorKit;
028:
029: /**
030: * This class is a wrapper of {@link DocumentParser}. <br>
031: * <br>
032: * Internally stores a reference to a DTD ({@link ParserDelegator#defaultDTD})
033: * which is filled with <code>html32.bdtd</code>, a file located at the classpath
034: * with the default DTD content (HTML 3.2) in ASN1 format. Then, instances
035: * a {@link DocumentParser} with this dtd. <br>
036: * <br>
037: * So, when the method
038: * {@link ParserDelegator#parse(Reader, javax.swing.text.html.HTMLEditorKit.ParserCallback, boolean) parse(Reader, HTMLEditorKit.ParserCallback, boolean)}
039: * is invoked, its <em>"delegates"</em> to a {@link DocumentParser}.
040: */
041: public class ParserDelegator extends HTMLEditorKit.Parser implements
042: Serializable {
043:
044: /**
045: * The name of the default dtd.
046: */
047: private static final String DEFAULT_DTD_NAME = "html32";
048:
049: /**
050: * Stores the default DTD (the content of the file <code>html32.bdtd</code>).
051: */
052: private static DTD defaultDTD;
053:
054: /**
055: * Sets {@link ParserDelegator#defaultDTD} with the <code>html32.bdtd</code>
056: * file by calling the method {@link ParserDelegator#setDefaultDTD()}.
057: */
058: public ParserDelegator() {
059: setDefaultDTD();
060: }
061:
062: /**
063: * Simply calls the method
064: * {@link javax.swing.text.html.parser.DocumentParser#parse(Reader, javax.swing.text.html.HTMLEditorKit.ParserCallback, boolean) parse(Reader, HTMLEditorKit.ParserCallback, boolean)}
065: * of the wrapped {@link javax.swing.text.html.parser.DocumentParser} with
066: * the same arguments
067: *
068: * @param r
069: * the reader
070: * @param cb
071: * the callback
072: * @param ignoreCharSet
073: * the ignoreCharSet
074: * @throws IOException
075: * if the {@link DocumentParser} propagates it
076: */
077: public void parse(final Reader r,
078: final HTMLEditorKit.ParserCallback cb,
079: final boolean ignoreCharSet) throws IOException {
080: DocumentParser dp = new DocumentParser(defaultDTD);
081: dp.parse(r, cb, ignoreCharSet);
082: }
083:
084: /**
085: * Reads the DTD content from the file called <code>name</code> + "bdtd"
086: * located in the classpath (if there is any) and fills the <code>dtd</code>
087: * with it. Then, returns <code>dtd</code>. <br>
088: * <br>
089: * The complete behavior is the following:
090: * <ol>
091: * <li> Finds the resource (the ASN1 binary file) in the classpath by
092: * appending ".bdtd" to <code>name</code>.
093: * <li> Creates an stream from this file and adds the information contained
094: * into <code>dtd</code> by calling its {@link DTD#read(DataInputStream)}
095: * method
096: * <li> Returns the <code>dtd</code>
097: * </ol>
098: * <br>
099: * Notice that this method catches any {@link Exception} and ignores it.
100: * It's the same behavior as the reference implementation.
101: *
102: * @param dtd
103: * the dtd to be filled
104: * @param name
105: * the name of the file located in the classpath (without .bdtd)
106: * @return the <code>dtd</code>
107: */
108: protected static DTD createDTD(final DTD dtd, final String name) {
109: try {
110: String oldName = dtd.name;
111: // gets the location of the harcoded file that is located in the
112: // classpath ...
113: // fills the DTD ...
114: dtd.read(new DataInputStream(ParserDelegator.class
115: .getResourceAsStream(name + ".bdtd")));
116: dtd.name = oldName;
117: DTD.putDTDHash(name, dtd);
118: } catch (Exception e) {
119: // ignores any exception (same as Reference Implementation)
120: }
121: return dtd;
122: }
123:
124: /**
125: * Sets the content of {@link ParserDelegator#defaultDTD}. Internally,
126: * calls {@link ParserDelegator#createDTD(DTD, String)} with
127: * {@link ParserDelegator#defaultDTD} and
128: * {@link ParserDelegator#DEFAULT_DTD_NAME} as arguments.
129: *
130: * Notice that {@link ParserDelegator#defaultDTD} is cached. It means that
131: * it's filled only once.
132: */
133: protected static synchronized void setDefaultDTD() {
134: if (defaultDTD == null) {
135: defaultDTD = new DTD(DEFAULT_DTD_NAME);
136: createDTD(defaultDTD, DEFAULT_DTD_NAME);
137: }
138: }
139: }
|