KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > enhydra > apache > html > dom > HTMLBuilder


1 /*
2  * The Apache Software License, Version 1.1
3  *
4  *
5  * Copyright (c) 1999,2000 The Apache Software Foundation. All rights
6  * reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * 1. Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  *
15  * 2. Redistributions in binary form must reproduce the above copyright
16  * notice, this list of conditions and the following disclaimer in
17  * the documentation and/or other materials provided with the
18  * distribution.
19  *
20  * 3. The end-user documentation included with the redistribution,
21  * if any, must include the following acknowledgment:
22  * "This product includes software developed by the
23  * Apache Software Foundation (http://www.apache.org/)."
24  * Alternately, this acknowledgment may appear in the software itself,
25  * if and wherever such third-party acknowledgments normally appear.
26  *
27  * 4. The names "Xerces" and "Apache Software Foundation" must
28  * not be used to endorse or promote products derived from this
29  * software without prior written permission. For written
30  * permission, please contact apache@apache.org.
31  *
32  * 5. Products derived from this software may not be called "Apache",
33  * nor may "Apache" appear in their name, without prior written
34  * permission of the Apache Software Foundation.
35  *
36  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
37  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
38  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
39  * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
40  * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
41  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
42  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
43  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
44  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
45  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
46  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
47  * SUCH DAMAGE.
48  * ====================================================================
49  *
50  * This software consists of voluntary contributions made by many
51  * individuals on behalf of the Apache Software Foundation and was
52  * originally based on software copyright (c) 1999, International
53  * Business Machines, Inc., http://www.apache.org. For more
54  * information on the Apache Software Foundation, please see
55  * <http://www.apache.org/>.
56  */

57 package org.enhydra.apache.html.dom;
58
59
60 import java.util.Vector JavaDoc;
61
62 import org.enhydra.apache.xerces.dom.ElementImpl;
63 import org.enhydra.apache.xerces.dom.ProcessingInstructionImpl;
64 import org.enhydra.apache.xerces.dom.TextImpl;
65 import org.w3c.dom.Node JavaDoc;
66 import org.w3c.dom.html.HTMLDocument;
67 import org.xml.sax.AttributeList JavaDoc;
68 import org.xml.sax.DocumentHandler JavaDoc;
69 import org.xml.sax.Locator JavaDoc;
70 import org.xml.sax.SAXException JavaDoc;
71
72
73 /**
74  * This is a SAX document handler that is used to build an HTML document.
75  * It can build a document from any SAX parser, but is specifically tuned
76  * for working with the OpenXML HTML parser.
77  *
78  *
79  * @version $Revision: 1.2 $ $Date: 2005/01/26 08:28:44 $
80  * @author <a HREF="mailto:arkin@openxml.org">Assaf Arkin</a>
81  */

82 public class HTMLBuilder
83     implements DocumentHandler JavaDoc
84 {
85
86
87     /**
88      * The document that is being built.
89      */

90     protected HTMLDocumentImpl _document;
91     
92     
93     /**
94      * The current node in the document into which elements, text and
95      * other nodes will be inserted. This starts as the document iself
96      * and reflects each element that is currently being parsed.
97      */

98     protected ElementImpl _current;
99     
100     /**
101      * A reference to the current locator, this is generally the parser
102      * itself. The locator is used to locate errors and identify the
103      * source locations of elements.
104      */

105     private Locator JavaDoc _locator;
106
107
108     /**
109      * Applies only to whitespace appearing between element tags in element content,
110      * as per the SAX definition, and true by default.
111      */

112     private boolean _ignoreWhitespace = true;
113
114
115     /**
116      * Indicates whether finished building a document. If so, can start building
117      * another document. Must be initially true to get the first document processed.
118      */

119     private boolean _done = true;
120
121
122     /**
123      * The document is only created the same time as the document element, however, certain
124      * nodes may precede the document element (comment and PI), and they are accumulated
125      * in this vector.
126      */

127     protected Vector JavaDoc _preRootNodes;
128
129     
130     public void startDocument()
131         throws SAXException JavaDoc
132     {
133         if ( ! _done )
134         throw new SAXException JavaDoc( "HTM001 State error: startDocument fired twice on one builder." );
135     _document = null;
136     _done = false;
137     }
138
139
140     public void endDocument()
141         throws SAXException JavaDoc
142     {
143         if ( _document == null )
144             throw new SAXException JavaDoc( "HTM002 State error: document never started or missing document element." );
145     if ( _current != null )
146         throw new SAXException JavaDoc( "HTM003 State error: document ended before end of document element." );
147         _current = null;
148     _done = true;
149     }
150
151
152     public synchronized void startElement( String JavaDoc tagName, AttributeList JavaDoc attrList )
153         throws SAXException JavaDoc
154     {
155         ElementImpl elem;
156         int i;
157         
158     if ( tagName == null )
159         throw new SAXException JavaDoc( "HTM004 Argument 'tagName' is null." );
160
161     // If this is the root element, this is the time to create a new document,
162
// because only know we know the document element name and namespace URI.
163
if ( _document == null )
164     {
165         // No need to create the element explicitly.
166
_document = new HTMLDocumentImpl();
167         elem = (ElementImpl) _document.getDocumentElement();
168         _current = elem;
169         if ( _current == null )
170         throw new SAXException JavaDoc( "HTM005 State error: Document.getDocumentElement returns null." );
171
172         // Insert nodes (comment and PI) that appear before the root element.
173
if ( _preRootNodes != null )
174         {
175         for ( i = _preRootNodes.size() ; i-- > 0 ; )
176             _document.insertBefore( (Node JavaDoc) _preRootNodes.elementAt( i ), elem );
177         _preRootNodes = null;
178         }
179          
180     }
181     else
182     {
183         // This is a state error, indicates that document has been parsed in full,
184
// or that there are two root elements.
185
if ( _current == null )
186         throw new SAXException JavaDoc( "HTM006 State error: startElement called after end of document element." );
187         elem = (ElementImpl) _document.createElement( tagName );
188         _current.appendChild( elem );
189         _current = elem;
190     }
191
192     // Add the attributes (specified and not-specified) to this element.
193
if ( attrList != null )
194         {
195             for ( i = 0 ; i < attrList.getLength() ; ++ i )
196                 elem.setAttribute( attrList.getName( i ), attrList.getValue( i ) );
197         }
198     }
199
200     
201     public void endElement( String JavaDoc tagName )
202         throws SAXException JavaDoc
203     {
204
205         if ( _current == null )
206             throw new SAXException JavaDoc( "HTM007 State error: endElement called with no current node." );
207     if ( ! _current.getNodeName().equals( tagName ) )
208         throw new SAXException JavaDoc( "HTM008 State error: mismatch in closing tag name " + tagName + "\n" + tagName);
209
210     // Move up to the parent element. When you reach the top (closing the root element).
211
// the parent is document and current is null.
212
if ( _current.getParentNode() == _current.getOwnerDocument() )
213         _current = null;
214     else
215         _current = (ElementImpl) _current.getParentNode();
216     }
217
218
219     public void characters( String JavaDoc text )
220         throws SAXException JavaDoc
221     {
222     if ( _current == null )
223             throw new SAXException JavaDoc( "HTM009 State error: character data found outside of root element." );
224     _current.appendChild( new TextImpl( _document, text ) );
225     }
226
227     
228     public void characters( char[] text, int start, int length )
229         throws SAXException JavaDoc
230     {
231     if ( _current == null )
232             throw new SAXException JavaDoc( "HTM010 State error: character data found outside of root element." );
233     _current.appendChild( new TextImpl( _document, new String JavaDoc( text, start, length ) ) );
234     }
235     
236     
237     public void ignorableWhitespace( char[] text, int start, int length )
238         throws SAXException JavaDoc
239     {
240         Node JavaDoc node;
241         
242         if ( ! _ignoreWhitespace )
243         _current.appendChild( new TextImpl( _document, new String JavaDoc( text, start, length ) ) );
244      }
245     
246     
247     public void processingInstruction( String JavaDoc target, String JavaDoc instruction )
248         throws SAXException JavaDoc
249     {
250         Node JavaDoc node;
251         
252     // Processing instruction may appear before the document element (in fact, before the
253
// document has been created, or after the document element has been closed.
254
if ( _current == null && _document == null )
255     {
256         if ( _preRootNodes == null )
257         _preRootNodes = new Vector JavaDoc();
258         _preRootNodes.addElement( new ProcessingInstructionImpl( null, target, instruction ) );
259     }
260     else
261         if ( _current == null && _document != null )
262         _document.appendChild( new ProcessingInstructionImpl( _document, target, instruction ) );
263     else
264         _current.appendChild( new ProcessingInstructionImpl( _document, target, instruction ) );
265     }
266     
267     
268     public HTMLDocument getHTMLDocument()
269     {
270         return (HTMLDocument) _document;
271     }
272
273     
274     public void setDocumentLocator( Locator JavaDoc locator )
275     {
276         _locator = locator;
277     }
278
279
280 }
281
Popular Tags