View Javadoc

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   * SaxHandlerDelegate - provides a clean interface between the
14   *   Byacc/J generated HtmlParse and the SaxParser.
15   */
16  
17  public class DebugParserDelegate implements ParserDelegate {
18  
19  	private HtmlParser parser = null;
20  	private XMLReader reader = null;
21  	private ContentHandler contentHandler = null;
22  	private LexicalHandler lexicalHandler = null; 		// this one my not exist for Sax parser/Sax client combo
23  
24  	private org.xml.sax.helpers.AttributesImpl attrList;   // collect attributes in a list
25  
26  
27  	public DebugParserDelegate(HtmlParser HtmlParser) {
28  		this.parser = parser;
29  		attrList = new org.xml.sax.helpers.AttributesImpl();
30  	}
31  
32  
33  	// ContentHandler interface methods.
34  	// If any of these fire a SAXException, it is reported to parser.yyerror()
35  
36  	/***
37  	 * Parse a startDocument event and pass it to the resigtered content handler.
38  	 * This method fires in response to a HtmlParser.EOF lexer token beging recognised.
39  	 * SOF is a virtual token fired as the first event after the file is opened.
40  	 */
41  	public void startDocument() 
42          {
43  		try {
44  		    if (contentHandler != null)
45  			contentHandler.startDocument();	
46                          
47  			System.out.println("Debug: document started");
48  		}
49  		catch (SAXException ex)
50  		{
51  		    parser.yyerror(ex.getMessage());
52  		}
53  	}
54  
55  
56        /*** 
57          * Parse a PI and pass it to the contentHandler event
58          *  (does not pass xml declaration:  <?xml version = 1>)
59  		* Separates the target from the data by using whitespace.
60          * 
61          */ 
62  	public void processingInstruction(HtmlParserVal target, HtmlParserVal lval)
63  	{
64  		try {
65              if (contentHandler != null) {
66                  StringTokenizer stok = new StringTokenizer(lval.sval);  // default delim = \sp
67                  
68                  if (stok.hasMoreElements())
69                  {
70                      String data;
71                      if (stok.hasMoreElements())
72                          data = stok.nextToken();
73                      else
74                          data = "";
75                      if (!target.equals("xml"))
76                          contentHandler.processingInstruction(target.toString(), data);
77                  }
78              }
79  		}
80  		catch (SAXException ex)
81  		{
82  			parser.yyerror(ex.getMessage());
83  		}
84  	}
85  
86  	/***
87    	 * Initialize the start of a start element. Prepares the attribute list
88  	 * to collect any attributes.
89  	 */
90  	public void startElement() 
91  	{
92  		attrList.clear();
93  	}
94  
95  	/***
96            * Adds an attribute to the list. The name of the attribute is normalized
97            * to lowercase 
98  	  */
99  	public void addAttribute(String name, String value) {
100 		attrList.addAttribute("", "", name, "NMTOKEN", value);
101 		System.out.println("attribute added " + name + " = \"" + value + "\"");
102 	}
103 
104 	public HtmlParserVal getAttributes() {
105 		HtmlParserVal aList = new HtmlParserVal(attrList);
106 		return aList;
107 	}
108 
109 	public void startElement(HtmlParserVal lval, HtmlParserVal attrList) {
110 		try {
111 			if (contentHandler != null)
112 			{
113 				 contentHandler.startElement("", lval.sval, "", (Attributes)attrList.obj);
114 			}
115 		}
116 		catch (SAXException ex)
117 		{
118 			parser.yyerror(ex.getMessage());
119 		}
120 	}
121 
122 	/***
123 	 * Fire startElement event. Note handled the actual beginning of the element by now
124 	 *  and have collected all attributes (if any)
125 	 */
126 	public void startElement(HtmlParserVal lval) {
127             try {
128                 if (contentHandler != null)
129                 {
130                     contentHandler.startElement("", lval.sval, "", attrList);
131                 }
132             }
133             catch (SAXException ex)
134             {
135                 parser.yyerror(ex.getMessage());
136             }
137 	}
138 
139 
140 	/***
141      * collect characters from parse stream. Unwrap the HtmlParserVal.sval 
142 	 * String to a character array. 
143      * TODO: After creating a LexicalHandler, make sure this gets called
144 	 *       in the comment state.
145      * TODO: This might be better done in the collection process
146      *   rather than always using a String. I.e. getting a bunch of chars instead of
147      *   incrementally appending one char at a time from yytext() 
148      */
149 	public void characters(HtmlParserVal lval) 
150 	{
151             try {
152                 if (contentHandler != null) // first unwrap to wrap later? for speed?
153                 {
154                     char ch[] = lval.sval.toCharArray();		
155                     contentHandler.characters(ch, 0, lval.sval.length());
156                 }
157             }
158             catch (SAXException ex)
159             {
160                     parser.yyerror(ex.getMessage());
161             }
162 	}
163 
164 
165 	/***
166      *  Fire endElement event. The name of the element is passed to the event handler.
167 	 *   Note these might be optionally missing in the HTML case.
168      */
169 	public void endElement(HtmlParserVal lval) 
170 	{
171             try {
172                 if (contentHandler != null)
173                     contentHandler.endElement("", lval.sval, "");
174             }
175             catch (SAXException ex)
176             {
177                 parser.yyerror(ex.getMessage());
178             }
179     }
180 
181 	/***
182 	 * Fire endDocument event.
183 	 */
184 	public void endDocument() 
185 	{
186             try {
187                 if (contentHandler != null)
188                     contentHandler.endDocument();
189             }
190             catch (SAXException ex)
191             {
192                 parser.yyerror(ex.getMessage());
193             }
194 	}
195 
196 	// LexicalHandler interface functions.
197 
198 	/***
199 	 * comment handler
200 	 * Note, these are delegate to the XMLReader's LexicalHandler if any
201 	 * TODO:  Check the property of the reader for its existance.
202 	 */
203 	public void comment(HtmlParserVal lval) {
204             try {
205                 if (lexicalHandler != null)
206                 {
207                     char ch[] = lval.sval.toCharArray();		
208                     lexicalHandler.comment(ch, 0, lval.sval.length());
209                 }
210             }
211             catch (SAXException ex)
212             {
213                 parser.yyerror(ex.getMessage());
214             }
215 	}
216 
217 
218 	/***
219 	 * CDATA handler
220 	 * Note, these are delegate to the XMLReader's LexicalHandler if any
221 	 * 	This only marks the start boundary condition. Text still goes through characters()
222 	 */
223 	public void startCDATA() {
224             try {
225                 if (lexicalHandler != null)
226                 {
227                     lexicalHandler.startCDATA();
228                 }
229             }
230             catch (SAXException ex)
231             {
232                     parser.yyerror(ex.getMessage());
233             }
234 	}
235 
236 	/***
237 	 * CDATA handler
238 	 * Note, these are delegate to the XMLReader's LexicalHandler if any
239 	 * 	This only marks the end boundary of the CDATA section. Text still goes through characters()
240 	 */
241 	public void endCDATA() {
242             try {
243                 if (lexicalHandler != null)
244                 {
245                     lexicalHandler.endCDATA();
246                 }
247             }
248             catch (SAXException ex)
249             {
250                     parser.yyerror(ex.getMessage());
251             }
252 	}
253 
254 	/***
255 	 * Start the beginning of the DOCTYPE (DTD) declaration
256 	 * Note, these are delegate to the XMLReader's LexicalHandler if any
257 	 */
258 	public void startDTD(HtmlParserVal lval) {
259             try {
260                if (lexicalHandler != null)
261                 {
262                     StringTokenizer stok = new StringTokenizer(lval.sval);  // default delim = \sp
263 
264                     if (stok.hasMoreElements())
265                     {
266                         String target = stok.nextToken();
267                         String data;
268                         if (stok.hasMoreElements())
269                             data = stok.nextToken();
270                         else
271                             data = "";
272 
273                         lexicalHandler.startDTD(target, data, null);
274                     }
275                 }
276             }
277             catch (SAXException ex)
278             {
279                     parser.yyerror(ex.getMessage());
280             }
281 	}
282 
283 	/***
284      *  End the DOCTYPE declaration
285      */
286 	public void endDTD()	{
287             try {
288                 if (lexicalHandler != null)
289                     lexicalHandler.endDTD();
290             }
291             catch (SAXException ex)
292             {
293                     parser.yyerror(ex.getMessage());
294             }
295 	}
296 
297 
298 
299 
300 
301     /***
302      * used by the SaxParser to set itself in ParserDelegate
303      */
304     public void setXMLReader(XMLReader reader) {
305             this.reader = reader;
306 
307         try {
308             if (reader != null)
309             {
310                 contentHandler = reader.getContentHandler(); // good idea to init first
311                 lexicalHandler = (LexicalHandler)reader.getProperty("http://xml.org/sax/properties/lexical-handler");
312             }
313         }
314         catch (SAXNotRecognizedException ex)
315         {
316                 System.err.println("No lexical handler set in property 'http://xml.org/sax/properties/lexical-handler'");
317         }
318         catch (SAXNotSupportedException ex)
319         {
320                 System.err.println("Lexical handler property not supported");
321         }
322 
323     }
324 
325 }