blob: 8db17537187b108c21780b6d9db789a500f6ed51 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2003-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26package com.sun.rowset.internal;
27
28import java.sql.*;
29import javax.sql.*;
30import java.io.*;
31
32import org.xml.sax.*;
33import org.xml.sax.helpers.*;
34import javax.xml.parsers.*;
35
36import com.sun.rowset.*;
37import java.text.MessageFormat;
38import javax.sql.rowset.*;
39import javax.sql.rowset.spi.*;
40
41/**
42 * An implementation of the <code>XmlReader</code> interface, which
43 * reads and parses an XML formatted <code>WebRowSet</code> object.
44 * This implementation uses an <code>org.xml.sax.Parser</code> object
45 * as its parser.
46 */
47public class WebRowSetXmlReader implements XmlReader, Serializable {
48
49 /**
50 * Parses the given <code>WebRowSet</code> object, getting its input from
51 * the given <code>java.io.Reader</code> object. The parser will send
52 * notifications of parse events to the rowset's
53 * <code>XmlReaderDocHandler</code>, which will build the rowset as
54 * an XML document.
55 * <P>
56 * This method is called internally by the method
57 * <code>WebRowSet.readXml</code>.
58 * <P>
59 * If a parsing error occurs, the exception thrown will include
60 * information for locating the error in the original XML document.
61 *
62 * @param caller the <code>WebRowSet</code> object to be parsed, whose
63 * <code>xmlReader</code> field must contain a reference to
64 * this <code>XmlReader</code> object
65 * @param reader the <code>java.io.Reader</code> object from which
66 * the parser will get its input
67 * @exception SQLException if a database access error occurs or
68 * this <code>WebRowSetXmlReader</code> object is not the
69 * reader for the given rowset
70 * @see XmlReaderContentHandler
71 */
72
73 private JdbcRowSetResourceBundle resBundle;
74
75 public WebRowSetXmlReader(){
76 try {
77 resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
78 } catch(IOException ioe) {
79 throw new RuntimeException(ioe);
80 }
81 }
82
83 public void readXML(WebRowSet caller, java.io.Reader reader) throws SQLException {
84 try {
85 // Crimson Parser(as in J2SE 1.4.1 is NOT able to handle
86 // Reader(s)(FileReader).
87 //
88 // But getting the file as a Stream works fine. So we are going to take
89 // the reader but send it as a InputStream to the parser. Note that this
90 // functionality needs to work against any parser
91 // Crimson(J2SE 1.4.x) / Xerces(J2SE 1.5.x).
92 InputSource is = new InputSource(reader);
93 DefaultHandler dh = new XmlErrorHandler();
94 XmlReaderContentHandler hndr = new XmlReaderContentHandler((RowSet)caller);
95 SAXParserFactory factory = SAXParserFactory.newInstance();
96 factory.setNamespaceAware(true);
97 factory.setValidating(true);
98 SAXParser parser = factory.newSAXParser() ;
99
100 parser.setProperty(
101 "http://java.sun.com/xml/jaxp/properties/schemaLanguage", "http://www.w3.org/2001/XMLSchema");
102
103 XMLReader reader1 = parser.getXMLReader() ;
104 reader1.setEntityResolver(new XmlResolver());
105 reader1.setContentHandler(hndr);
106
107 reader1.setErrorHandler(dh);
108
109 reader1.parse(is);
110
111 } catch (SAXParseException err) {
112 System.out.println (MessageFormat.format(resBundle.handleGetObject("wrsxmlreader.parseerr").toString(), new Object[]{ err.getMessage (), err.getLineNumber(), err.getSystemId()}));
113 err.printStackTrace();
114 throw new SQLException(err.getMessage());
115
116 } catch (SAXException e) {
117 Exception x = e;
118 if (e.getException () != null)
119 x = e.getException();
120 x.printStackTrace ();
121 throw new SQLException(x.getMessage());
122
123 }
124
125 // Will be here if trying to write beyond the RowSet limits
126
127 catch (ArrayIndexOutOfBoundsException aie) {
128 throw new SQLException(resBundle.handleGetObject("wrsxmlreader.invalidcp").toString());
129 }
130 catch (Throwable e) {
131 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("wrsxmlreader.readxml").toString() , e.getMessage()));
132 }
133
134 }
135
136
137 /**
138 * Parses the given <code>WebRowSet</code> object, getting its input from
139 * the given <code>java.io.InputStream</code> object. The parser will send
140 * notifications of parse events to the rowset's
141 * <code>XmlReaderDocHandler</code>, which will build the rowset as
142 * an XML document.
143 * <P>
144 * Using streams is a much faster way than using <code>java.io.Reader</code>
145 * <P>
146 * This method is called internally by the method
147 * <code>WebRowSet.readXml</code>.
148 * <P>
149 * If a parsing error occurs, the exception thrown will include
150 * information for locating the error in the original XML document.
151 *
152 * @param caller the <code>WebRowSet</code> object to be parsed, whose
153 * <code>xmlReader</code> field must contain a reference to
154 * this <code>XmlReader</code> object
155 * @param iStream the <code>java.io.InputStream</code> object from which
156 * the parser will get its input
157 * @throws SQLException if a database access error occurs or
158 * this <code>WebRowSetXmlReader</code> object is not the
159 * reader for the given rowset
160 * @see XmlReaderContentHandler
161 */
162 public void readXML(WebRowSet caller, java.io.InputStream iStream) throws SQLException {
163 try {
164 InputSource is = new InputSource(iStream);
165 DefaultHandler dh = new XmlErrorHandler();
166
167 XmlReaderContentHandler hndr = new XmlReaderContentHandler((RowSet)caller);
168 SAXParserFactory factory = SAXParserFactory.newInstance();
169 factory.setNamespaceAware(true);
170 factory.setValidating(true);
171
172 SAXParser parser = factory.newSAXParser() ;
173
174 parser.setProperty("http://java.sun.com/xml/jaxp/properties/schemaLanguage",
175 "http://www.w3.org/2001/XMLSchema");
176
177 XMLReader reader1 = parser.getXMLReader() ;
178 reader1.setEntityResolver(new XmlResolver());
179 reader1.setContentHandler(hndr);
180
181 reader1.setErrorHandler(dh);
182
183 reader1.parse(is);
184
185 } catch (SAXParseException err) {
186 System.out.println (MessageFormat.format(resBundle.handleGetObject("wrsxmlreader.parseerr").toString(), new Object[]{err.getLineNumber(), err.getSystemId() }));
187 System.out.println(" " + err.getMessage ());
188 err.printStackTrace();
189 throw new SQLException(err.getMessage());
190
191 } catch (SAXException e) {
192 Exception x = e;
193 if (e.getException () != null)
194 x = e.getException();
195 x.printStackTrace ();
196 throw new SQLException(x.getMessage());
197
198 }
199
200 // Will be here if trying to write beyond the RowSet limits
201
202 catch (ArrayIndexOutOfBoundsException aie) {
203 throw new SQLException(resBundle.handleGetObject("wrsxmlreader.invalidcp").toString());
204 }
205
206 catch (Throwable e) {
207 throw new SQLException(MessageFormat.format(resBundle.handleGetObject("wrsxmlreader.readxml").toString() , e.getMessage()));
208 }
209 }
210
211 /**
212 * For code coverage purposes only right now
213 *
214 */
215
216 public void readData(RowSetInternal caller) {
217 }
218
219}