KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > hotsax > html > sax > ParserDelegate


1 package hotsax.html.sax;
2
3 import org.xml.sax.*;
4 import org.xml.sax.helpers.*;
5 import org.xml.sax.ext.*;
6
7 import java.io.*;
8 import java.util.*;
9
10
11
12 /**
13  * ParserDelegate - provides a clean interface between the
14  * Byacc/J generated HtmlParse and the SaxParser.
15  */

16
17 // TODO: Make this an interface, provide and implementation model
18
// This cleanly separates what is to be done from actually doing it
19
// That way a HtmlParser+HtmlLexer combo can be combined
20
// with something other than a SaxParser (Say a DOM)
21

22 public class ParserDelegate {
23
24         private HtmlParser parser = null;
25         private XMLReader reader = null;
26         private ContentHandler contentHandler = null;
27         private LexicalHandler lexicalHandler = null; // this one my not exist for Sax parser/Sax client combo
28

29         private org.xml.sax.helpers.AttributesImpl JavaDoc attrList; // collect attributes in a list
30

31
32     public ParserDelegate(HtmlParser HtmlParser) {
33         this.parser = parser;
34         attrList = new org.xml.sax.helpers.AttributesImpl JavaDoc();
35     }
36
37
38     // ContentHandler interface methods.
39
// If any of these fire a SAXException, it is reported to parser.yyerror()
40

41     /**
42      * Parse a startDocument event and pass it to the resigtered content handler.
43      * This method fires in response to a HtmlParser.EOF lexer token beging recognised.
44      * SOF is a virtual token fired as the first event after the file is opened.
45      */

46     public void startDocument()
47         {
48         try {
49             if (contentHandler != null)
50             contentHandler.startDocument();
51                         
52         }
53         catch (SAXException ex)
54         {
55             parser.yyerror(ex.getMessage());
56         }
57     }
58
59
60       /**
61         * Parse a PI and pass it to the contentHandler event
62         * (does not pass xml declaration: <?xml version = 1>)
63         * Separates the target from the data by using whitespace.
64         *
65         */

66     public void processingInstruction(HtmlParserVal lval)
67     {
68         try {
69             if (contentHandler != null) {
70                 StringTokenizer stok = new StringTokenizer(lval.sval); // default delim = \sp
71

72                 if (stok.hasMoreElements())
73                 {
74                     String JavaDoc target = stok.nextToken();
75                     String JavaDoc data;
76                     if (stok.hasMoreElements())
77                         data = stok.nextToken();
78                     else
79                         data = "";
80                     if (!target.equals("xml"))
81                         contentHandler.processingInstruction(target, data);
82                 }
83             }
84         }
85         catch (SAXException ex)
86         {
87             parser.yyerror(ex.getMessage());
88         }
89     }
90
91     /**
92      * Initialize the start of a start element. Prepares the attribute list
93      * to collect any attributes.
94      */

95     public void startElement()
96     {
97         attrList.clear();
98     }
99
100     /**
101           * Adds an attribute to the list. The name of the attribute is normalized
102           * to lowercase
103       */

104     public void addAttribute(HtmlParserVal lval)
105     {
106         if (lval instanceof hotsax.html.sax.Attribute)
107         {
108             Attribute attr = (Attribute)lval;
109                 attrList.addAttribute("", "", attr.getName().toLowerCase(), "NMTOKEN", attr.getValue());
110         }
111         else
112         {
113             System.err.println("Parser passed " + lval.getClass().getName() + " to delegate expecting Attribute");
114         }
115     }
116
117     /**
118      * Fire startElement event. Note handled the actual beginning of the element by now
119      * and have collected all attributes (if any)
120      */

121     public void startElement(HtmlParserVal lval)
122     {
123             try {
124                 if (contentHandler != null)
125                 {
126                     contentHandler.startElement("", lval.sval, "", attrList);
127                 }
128             }
129             catch (SAXException ex)
130             {
131                 parser.yyerror(ex.getMessage());
132             }
133     }
134
135
136     /**
137      * collect characters from parse stream. Unwrap the HtmlParserVal.sval
138      * String to a character array.
139      * TODO: After creating a LexicalHandler, make sure this gets called
140      * in the comment state.
141      * TODO: This might be better done in the collection process
142      * rather than always using a String. I.e. getting a bunch of chars instead of
143      * incrementally appending one char at a time from yytext()
144      */

145     public void characters(HtmlParserVal lval)
146     {
147             try {
148                 if (contentHandler != null) // first unwrap to wrap later? for speed?
149
{
150                     char ch[] = lval.sval.toCharArray();
151                     contentHandler.characters(ch, 0, lval.sval.length());
152                 }
153             }
154             catch (SAXException ex)
155             {
156                     parser.yyerror(ex.getMessage());
157             }
158     }
159
160
161     /**
162      * Fire endElement event. The name of the element is passed to the event handler.
163      * Note these might be optionally missing in the HTML case.
164      */

165     public void endElement(HtmlParserVal lval)
166     {
167             try {
168                 if (contentHandler != null)
169                     contentHandler.endElement("", lval.sval, "");
170             }
171             catch (SAXException ex)
172             {
173                 parser.yyerror(ex.getMessage());
174             }
175     }
176
177     /**
178      * Fire endDocument event.
179      */

180     public void endDocument()
181     {
182             try {
183                 if (contentHandler != null)
184                     contentHandler.endDocument();
185             }
186             catch (SAXException ex)
187             {
188                 parser.yyerror(ex.getMessage());
189             }
190     }
191
192     // LexicalHandler interface functions.
193

194     /**
195      * comment handler
196      * Note, these are delegate to the XMLReader's LexicalHandler if any
197      * TODO: Check the propery of the reader for its existance.
198      * TODO: add LexicalHandler to Sax client
199      */

200     public void comment(HtmlParserVal lval) {
201             try {
202                if (lexicalHandler != null)
203                     {
204                         char ch[] = lval.sval.toCharArray();
205                         lexicalHandler.comment(ch, 0, lval.sval.length());
206                     }
207                 }
208                 catch (SAXException ex)
209                 {
210                         parser.yyerror(ex.getMessage());
211                 }
212     }
213
214
215     /**
216      * CDATA handler
217      * Note, these are delegate to the XMLReader's LexicalHandler if any
218      * This only marks the start boundary condition. Text still goes through characters()
219      */

220     public void startCDATA() {
221             try {
222                 if (lexicalHandler != null)
223                 {
224                     lexicalHandler.startCDATA();
225                 }
226             }
227             catch (SAXException ex)
228             {
229                     parser.yyerror(ex.getMessage());
230             }
231     }
232
233     /**
234      * CDATA handler
235      * Note, these are delegate to the XMLReader's LexicalHandler if any
236      * This only marks the end boundary of the CDATA section. Text still goes through characters()
237      */

238     public void endCDATA() {
239             try {
240                 if (lexicalHandler != null)
241                 {
242                     lexicalHandler.endCDATA();
243                 }
244             }
245             catch (SAXException ex)
246             {
247                     parser.yyerror(ex.getMessage());
248             }
249     }
250
251     /**
252      * Start the beginning of the DOCTYPE (DTD) declaration
253      * Note, these are delegate to the XMLReader's LexicalHandler if any
254      */

255     public void startDTD(HtmlParserVal lval) {
256             try {
257                if (lexicalHandler != null)
258                 {
259                     StringTokenizer stok = new StringTokenizer(lval.sval); // default delim = \sp
260

261                     if (stok.hasMoreElements())
262                     {
263                         String JavaDoc target = stok.nextToken();
264                         String JavaDoc data;
265                         if (stok.hasMoreElements())
266                             data = stok.nextToken();
267                         else
268                             data = "";
269
270                         lexicalHandler.startDTD(target, data, null);
271                     }
272                 }
273             }
274             catch (SAXException ex)
275             {
276                     parser.yyerror(ex.getMessage());
277             }
278     }
279
280     /**
281      * End the DOCTYPE declaration
282      */

283     public void endDTD() {
284             try {
285                 if (lexicalHandler != null)
286                     lexicalHandler.endDTD();
287             }
288             catch (SAXException ex)
289             {
290                     parser.yyerror(ex.getMessage());
291             }
292     }
293
294
295
296
297
298     /**
299      * used by the SaxParser to set itself in ParserDelegate
300      */

301     public void setSaxParser(XMLReader reader) {
302             this.reader = reader;
303
304         try {
305             if (reader != null)
306             {
307                 contentHandler = reader.getContentHandler(); // good idea to init first
308
lexicalHandler = (LexicalHandler)reader.getProperty("http://xml.org/sax/properties/lexical-handler");
309             }
310         }
311         catch (SAXNotRecognizedException ex)
312         {
313                 System.err.println("no lexical handler installed");
314         }
315         catch (SAXNotSupportedException ex)
316         {
317                 System.err.println("no lexical handler installed");
318         }
319
320     }
321
322 }
323
Popular Tags