001: /*
002: * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.rowset.internal;
027:
028: import java.sql.*;
029: import javax.sql.*;
030: import java.io.*;
031:
032: import org.xml.sax.*;
033: import org.xml.sax.helpers.*;
034: import javax.xml.parsers.*;
035:
036: import com.sun.rowset.*;
037: import java.text.MessageFormat;
038: import javax.sql.rowset.*;
039: import javax.sql.rowset.spi.*;
040:
041: /**
042: * An implementation of the <code>XmlReader</code> interface, which
043: * reads and parses an XML formatted <code>WebRowSet</code> object.
044: * This implementation uses an <code>org.xml.sax.Parser</code> object
045: * as its parser.
046: */
047: public class WebRowSetXmlReader implements XmlReader, Serializable {
048:
049: /**
050: * Parses the given <code>WebRowSet</code> object, getting its input from
051: * the given <code>java.io.Reader</code> object. The parser will send
052: * notifications of parse events to the rowset's
053: * <code>XmlReaderDocHandler</code>, which will build the rowset as
054: * an XML document.
055: * <P>
056: * This method is called internally by the method
057: * <code>WebRowSet.readXml</code>.
058: * <P>
059: * If a parsing error occurs, the exception thrown will include
060: * information for locating the error in the original XML document.
061: *
062: * @param caller the <code>WebRowSet</code> object to be parsed, whose
063: * <code>xmlReader</code> field must contain a reference to
064: * this <code>XmlReader</code> object
065: * @param reader the <code>java.io.Reader</code> object from which
066: * the parser will get its input
067: * @exception SQLException if a database access error occurs or
068: * this <code>WebRowSetXmlReader</code> object is not the
069: * reader for the given rowset
070: * @see XmlReaderContentHandler
071: */
072:
073: private JdbcRowSetResourceBundle resBundle;
074:
075: public WebRowSetXmlReader() {
076: try {
077: resBundle = JdbcRowSetResourceBundle
078: .getJdbcRowSetResourceBundle();
079: } catch (IOException ioe) {
080: throw new RuntimeException(ioe);
081: }
082: }
083:
084: public void readXML(WebRowSet caller, java.io.Reader reader)
085: throws SQLException {
086: try {
087: // Crimson Parser(as in J2SE 1.4.1 is NOT able to handle
088: // Reader(s)(FileReader).
089: //
090: // But getting the file as a Stream works fine. So we are going to take
091: // the reader but send it as a InputStream to the parser. Note that this
092: // functionality needs to work against any parser
093: // Crimson(J2SE 1.4.x) / Xerces(J2SE 1.5.x).
094: InputSource is = new InputSource(reader);
095: DefaultHandler dh = new XmlErrorHandler();
096: XmlReaderContentHandler hndr = new XmlReaderContentHandler(
097: (RowSet) caller);
098: SAXParserFactory factory = SAXParserFactory.newInstance();
099: factory.setNamespaceAware(true);
100: factory.setValidating(true);
101: SAXParser parser = factory.newSAXParser();
102:
103: parser
104: .setProperty(
105: "http://java.sun.com/xml/jaxp/properties/schemaLanguage",
106: "http://www.w3.org/2001/XMLSchema");
107:
108: XMLReader reader1 = parser.getXMLReader();
109: reader1.setEntityResolver(new XmlResolver());
110: reader1.setContentHandler(hndr);
111:
112: reader1.setErrorHandler(dh);
113:
114: reader1.parse(is);
115:
116: } catch (SAXParseException err) {
117: System.out.println(MessageFormat.format(resBundle
118: .handleGetObject("wrsxmlreader.parseerr")
119: .toString(), new Object[] { err.getMessage(),
120: err.getLineNumber(), err.getSystemId() }));
121: err.printStackTrace();
122: throw new SQLException(err.getMessage());
123:
124: } catch (SAXException e) {
125: Exception x = e;
126: if (e.getException() != null)
127: x = e.getException();
128: x.printStackTrace();
129: throw new SQLException(x.getMessage());
130:
131: }
132:
133: // Will be here if trying to write beyond the RowSet limits
134:
135: catch (ArrayIndexOutOfBoundsException aie) {
136: throw new SQLException(resBundle.handleGetObject(
137: "wrsxmlreader.invalidcp").toString());
138: } catch (Throwable e) {
139: throw new SQLException(MessageFormat.format(
140: resBundle.handleGetObject("wrsxmlreader.readxml")
141: .toString(), e.getMessage()));
142: }
143:
144: }
145:
146: /**
147: * Parses the given <code>WebRowSet</code> object, getting its input from
148: * the given <code>java.io.InputStream</code> object. The parser will send
149: * notifications of parse events to the rowset's
150: * <code>XmlReaderDocHandler</code>, which will build the rowset as
151: * an XML document.
152: * <P>
153: * Using streams is a much faster way than using <code>java.io.Reader</code>
154: * <P>
155: * This method is called internally by the method
156: * <code>WebRowSet.readXml</code>.
157: * <P>
158: * If a parsing error occurs, the exception thrown will include
159: * information for locating the error in the original XML document.
160: *
161: * @param caller the <code>WebRowSet</code> object to be parsed, whose
162: * <code>xmlReader</code> field must contain a reference to
163: * this <code>XmlReader</code> object
164: * @param iStream the <code>java.io.InputStream</code> object from which
165: * the parser will get its input
166: * @throws SQLException if a database access error occurs or
167: * this <code>WebRowSetXmlReader</code> object is not the
168: * reader for the given rowset
169: * @see XmlReaderContentHandler
170: */
171: public void readXML(WebRowSet caller, java.io.InputStream iStream)
172: throws SQLException {
173: try {
174: InputSource is = new InputSource(iStream);
175: DefaultHandler dh = new XmlErrorHandler();
176:
177: XmlReaderContentHandler hndr = new XmlReaderContentHandler(
178: (RowSet) caller);
179: SAXParserFactory factory = SAXParserFactory.newInstance();
180: factory.setNamespaceAware(true);
181: factory.setValidating(true);
182:
183: SAXParser parser = factory.newSAXParser();
184:
185: parser
186: .setProperty(
187: "http://java.sun.com/xml/jaxp/properties/schemaLanguage",
188: "http://www.w3.org/2001/XMLSchema");
189:
190: XMLReader reader1 = parser.getXMLReader();
191: reader1.setEntityResolver(new XmlResolver());
192: reader1.setContentHandler(hndr);
193:
194: reader1.setErrorHandler(dh);
195:
196: reader1.parse(is);
197:
198: } catch (SAXParseException err) {
199: System.out.println(MessageFormat.format(resBundle
200: .handleGetObject("wrsxmlreader.parseerr")
201: .toString(), new Object[] { err.getLineNumber(),
202: err.getSystemId() }));
203: System.out.println(" " + err.getMessage());
204: err.printStackTrace();
205: throw new SQLException(err.getMessage());
206:
207: } catch (SAXException e) {
208: Exception x = e;
209: if (e.getException() != null)
210: x = e.getException();
211: x.printStackTrace();
212: throw new SQLException(x.getMessage());
213:
214: }
215:
216: // Will be here if trying to write beyond the RowSet limits
217:
218: catch (ArrayIndexOutOfBoundsException aie) {
219: throw new SQLException(resBundle.handleGetObject(
220: "wrsxmlreader.invalidcp").toString());
221: }
222:
223: catch (Throwable e) {
224: throw new SQLException(MessageFormat.format(
225: resBundle.handleGetObject("wrsxmlreader.readxml")
226: .toString(), e.getMessage()));
227: }
228: }
229:
230: /**
231: * For code coverage purposes only right now
232: *
233: */
234:
235: public void readData(RowSetInternal caller) {
236: }
237:
238: }
|