KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > jboss > mq > xml > XElementProducer


1 /*
2 * JBoss, Home of Professional Open Source
3 * Copyright 2005, JBoss Inc., and individual contributors as indicated
4 * by the @authors tag. See the copyright.txt in the distribution for a
5 * full listing of individual contributors.
6 *
7 * This is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU Lesser General Public License as
9 * published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This software is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this software; if not, write to the Free
19 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
20 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
21 */

22 package org.jboss.mq.xml;
23
24 import java.util.Vector JavaDoc;
25 import javax.xml.parsers.SAXParser JavaDoc;
26 import javax.xml.parsers.SAXParserFactory JavaDoc;
27
28 import org.xml.sax.Attributes JavaDoc;
29 import org.xml.sax.InputSource JavaDoc;
30 import org.xml.sax.SAXException JavaDoc;
31 import org.xml.sax.XMLReader JavaDoc;
32 import org.xml.sax.helpers.DefaultHandler JavaDoc;
33
34 /**
35  * XElementProducer parses and provides an XElementConsumer XElement data. <p>
36  *
37  * An XElementProducer is a SAX based XML parser. This class provides a hybrid
38  * of the Event Based and DOM based XML parsing models. This is done by telling
39  * the XElementProducer which elements signal the start of a record, and when
40  * to generat an XElement. As the "record" XML elements are encountered,
41  * XElements are produced. These XElements create an in memory DOM tree of the
42  * element and all sub elements. After the "record" element has be fully read
43  * in through the use of SAX events, the "record" element, now in the form of
44  * an XElement, is passed to an XElementConsumer for processing.
45  *
46  * @author Hiram Chirino (Cojonudo14@hotmail.com)
47  * @created August 16, 2001
48  * @version $Revision: 37459 $
49  */

50 public class XElementProducer {
51
52    private XElementConsumer consumer;
53    private Vector JavaDoc targetRecords = new Vector JavaDoc();
54    private Handler JavaDoc handler = new Handler JavaDoc();
55    private Exception JavaDoc thrownError = null;
56
57    /**
58     * The Constructor must be passed the consumer object.
59     *
60     * @param consumerObject the object that will process data produced from
61     * this object.
62     */

63    public XElementProducer( XElementConsumer consumerObject ) {
64       consumer = consumerObject;
65    }
66
67    /**
68     * Adds a name to the list of element names which when encountered, will
69     * produce an XElement record.
70     *
71     * @param name
72     */

73    public void addElementRecord( String JavaDoc name ) {
74       targetRecords.addElement( name );
75    }
76
77    /**
78     * Clears all the previously added element record names.
79     */

80    public void clearElementRecords() {
81       targetRecords.removeAllElements();
82    }
83
84    /**
85     * Starts parsing a file. As "record" elements are encountered, record
86     * XElements are produced and given to the XElementConsumer to process.
87     *
88     * @param is Description of Parameter
89     * @throws Exception includes IO errors, parse errors, or Exceptions thrown
90     * from the RecordConsumer.
91     */

92    public void parse( java.io.InputStream JavaDoc is )
93       throws Exception JavaDoc {
94       if ( consumer == null ) {
95          throw new NullPointerException JavaDoc();
96       }
97       try {
98
99          SAXParserFactory JavaDoc factory = SAXParserFactory.newInstance();
100          SAXParser JavaDoc parser = factory.newSAXParser();
101
102          if ( consumer instanceof org.xml.sax.ErrorHandler JavaDoc ) {
103             XMLReader JavaDoc reader = parser.getXMLReader();
104             reader.setErrorHandler( ( org.xml.sax.ErrorHandler JavaDoc )consumer );
105          }
106          thrownError = null;
107          parser.parse( new InputSource JavaDoc( is ), handler );
108       } catch ( SAXException JavaDoc e ) {
109          if ( thrownError != null ) {
110             throw thrownError;
111          } else {
112             throw e;
113          }
114       }
115    }
116
117    /**
118     * Starts parsing a file. As "record" elements are encountered, record
119     * XElements are produced and given to the XElementConsumer to process.
120     *
121     * @param url Description of Parameter
122     * @throws Exception includes IO errors, parse errors, or Exceptions thrown
123     * from the RecordConsumer.
124     */

125    public void parse( java.net.URL JavaDoc url )
126       throws Exception JavaDoc {
127       if ( consumer == null ) {
128          throw new NullPointerException JavaDoc();
129       }
130       try {
131          SAXParserFactory JavaDoc factory = SAXParserFactory.newInstance();
132          SAXParser JavaDoc parser = factory.newSAXParser();
133
134          if ( consumer instanceof org.xml.sax.ErrorHandler JavaDoc ) {
135             XMLReader JavaDoc reader = parser.getXMLReader();
136             reader.setErrorHandler( ( org.xml.sax.ErrorHandler JavaDoc )consumer );
137          }
138          thrownError = null;
139          parser.parse( url.toExternalForm(), handler );
140       } catch ( SAXException JavaDoc e ) {
141          if ( thrownError != null ) {
142             throw thrownError;
143          } else {
144             throw e;
145          }
146       }
147    }
148
149    //
150
// INNER CLASS : Handler
151
// Used to handle for SAX events.
152
//
153
// If we get an element whose name is in targetRecords vector then
154
// we start a new root XElement and set currentXElement to this object.
155
// currentXElement is always the top element that is being processed.
156
// (He's working like the top pointer of a stack)
157
//
158
// As sub elements are encountered, they will be added to the currentXElement
159
// and then they become the currentXElement.
160
//
161
// When the end of an element is encountered, then currentXElement
162
// is set to the parent of currentXElement.
163
//
164
// Exception processing is a little trick, read on:
165
// An XElementConsumer is allowed to throw any kind of exception
166
// when processing records. But since the SAX event based parser only allows
167
// you to throw SAXExceptions from it's event handler methods, this class
168
// uses the thrownError variable to store the thrown event. A SAXException
169
// is then generated to stop the SAXParser and the XElementProducer.parse()
170
// method checks to see if the thrownError variable was set, if so, then
171
// it throws the exception stored in thrownError.
172
//
173
/**
174     * @created August 16, 2001
175     */

176    class Handler extends DefaultHandler JavaDoc {
177       private XElement currentXElement;
178
179       public void startDocument()
180          throws SAXException JavaDoc {
181          try {
182             consumer.documentStartEvent();
183          } catch ( Exception JavaDoc e ) {
184             thrownError = e;
185             throw new SAXException JavaDoc( e.toString() );
186          }
187       }
188
189       public void endDocument()
190          throws SAXException JavaDoc {
191          try {
192             consumer.documentEndEvent();
193          } catch ( Exception JavaDoc e ) {
194             thrownError = e;
195             throw new SAXException JavaDoc( e.toString() );
196          }
197       }
198
199       public void startElement( String JavaDoc uri, String JavaDoc localName, String JavaDoc qname, Attributes JavaDoc atts )
200          throws SAXException JavaDoc {
201          if ( currentXElement != null ) {
202             XElement o = new XElement( qname, atts );
203             currentXElement.addElement( o );
204             currentXElement = o;
205          } else {
206             if ( targetRecords.size() == 0 ) {
207                currentXElement = new XElement( qname, atts );
208             } else {
209                for ( int i = 0; i < targetRecords.size(); i++ ) {
210                   if ( qname.equals( targetRecords.elementAt( i ) ) ) {
211                      currentXElement = new XElement( qname, atts );
212                      break;
213                   }
214                }
215             }
216          }
217       }
218
219       public void endElement( String JavaDoc uri, String JavaDoc localName, String JavaDoc qName )
220          throws SAXException JavaDoc {
221          if ( currentXElement != null ) {
222             // Sanity Check :
223
if ( !qName.equals( currentXElement.getName() ) ) {
224                throw new SAXException JavaDoc( "XElement parsing sanitity check failed" );
225             }
226             XElement t = currentXElement;
227             currentXElement = currentXElement.getParent();
228             if ( currentXElement == null ) {
229                try {
230                   consumer.recordReadEvent( t );
231                } catch ( Exception JavaDoc e ) {
232                   thrownError = e;
233                   throw new SAXException JavaDoc( e.toString() );
234                }
235             }
236          }
237       }
238
239       public void characters( char[] chars, int start, int length ) {
240          if ( length == 0 ) {
241             return;
242          }
243          if ( currentXElement != null ) {
244             currentXElement.add( new String JavaDoc( chars, start, length ) );
245          }
246       }
247    }
248
249 }
250
Popular Tags