1/*
2 * Copyright (c) 2003, 2013, Oracle and/or its affiliates. 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.  Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26package com.sun.rowset;
27
28import java.sql.*;
29import javax.sql.*;
30import java.io.*;
31import java.math.*;
32import java.util.*;
33import java.text.*;
34
35import org.xml.sax.*;
36
37import javax.sql.rowset.*;
38import javax.sql.rowset.spi.*;
39
40import com.sun.rowset.providers.*;
41import com.sun.rowset.internal.*;
42
43/**
44 * The standard implementation of the <code>WebRowSet</code> interface. See the interface
45 * definition for full behavior and implementation requirements.
46 *
47 * @author Jonathan Bruce, Amit Handa
48 */
49public class WebRowSetImpl extends CachedRowSetImpl implements WebRowSet {
50
51    /**
52     * The <code>WebRowSetXmlReader</code> object that this
53     * <code>WebRowSet</code> object will call when the method
54     * <code>WebRowSet.readXml</code> is invoked.
55     */
56    private WebRowSetXmlReader xmlReader;
57
58    /**
59     * The <code>WebRowSetXmlWriter</code> object that this
60     * <code>WebRowSet</code> object will call when the method
61     * <code>WebRowSet.writeXml</code> is invoked.
62     */
63    private WebRowSetXmlWriter xmlWriter;
64
65    /* This stores the cursor position prior to calling the writeXML.
66     * This variable is used after the write to restore the position
67     * to the point where the writeXml was called.
68     */
69    private int curPosBfrWrite;
70
71    private SyncProvider provider;
72
73    /**
74     * Constructs a new <code>WebRowSet</code> object initialized with the
75     * default values for a <code>CachedRowSet</code> object instance. This
76     * provides the <code>RIOptimistic</code> provider to deliver
77     * synchronization capabilities to relational datastores and a default
78     * <code>WebRowSetXmlReader</code> object and a default
79     * <code>WebRowSetXmlWriter</code> object to enable XML output
80     * capabilities.
81     *
82     * @throws SQLException if an error occurs in configuring the default
83     * synchronization providers for relational and XML providers.
84     */
85    public WebRowSetImpl() throws SQLException {
86        super();
87
88        // %%%
89        // Needs to use to SPI  XmlReader,XmlWriters
90        //
91        xmlReader = new WebRowSetXmlReader();
92        xmlWriter = new WebRowSetXmlWriter();
93    }
94
95    /**
96     * Constructs a new <code>WebRowSet</code> object initialized with the
97     * synchronization SPI provider properties as specified in the <code>Hashtable</code>. If
98     * this hashtable is empty or is <code>null</code> the default constructor is invoked.
99     *
100     * @throws SQLException if an error occurs in configuring the specified
101     * synchronization providers for the relational and XML providers; or
102     * if the Hashtanle is null
103     */
104    @SuppressWarnings("rawtypes")
105    public WebRowSetImpl(Hashtable env) throws SQLException {
106
107        try {
108           resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
109        } catch(IOException ioe) {
110            throw new RuntimeException(ioe);
111        }
112
113        if ( env == null) {
114            throw new SQLException(resBundle.handleGetObject("webrowsetimpl.nullhash").toString());
115        }
116
117        String providerName =
118            (String)env.get(javax.sql.rowset.spi.SyncFactory.ROWSET_SYNC_PROVIDER);
119
120        // set the Reader, this maybe overridden latter
121        provider = SyncFactory.getInstance(providerName);
122
123        // xmlReader = provider.getRowSetReader();
124        // xmlWriter = provider.getRowSetWriter();
125    }
126
127   /**
128    * Populates this <code>WebRowSet</code> object with the
129    * data in the given <code>ResultSet</code> object and writes itself
130    * to the given <code>java.io.Writer</code> object in XML format.
131    * This includes the rowset's data,  properties, and metadata.
132    *
133    * @throws SQLException if an error occurs writing out the rowset
134    *          contents to XML
135    */
136    public void writeXml(ResultSet rs, java.io.Writer writer)
137        throws SQLException {
138            // WebRowSetImpl wrs = new WebRowSetImpl();
139            this.populate(rs);
140
141            // Store the cursor position before writing
142            curPosBfrWrite = this.getRow();
143
144            this.writeXml(writer);
145    }
146
147    /**
148     * Writes this <code>WebRowSet</code> object to the given
149     * <code>java.io.Writer</code> object in XML format. This
150     * includes the rowset's data,  properties, and metadata.
151     *
152     * @throws SQLException if an error occurs writing out the rowset
153     *          contents to XML
154     */
155    public void writeXml(java.io.Writer writer) throws SQLException {
156        // %%%
157        // This will change to a XmlReader, which over-rides the default
158        // Xml that is used when a WRS is instantiated.
159        // WebRowSetXmlWriter xmlWriter = getXmlWriter();
160        if (xmlWriter != null) {
161
162            // Store the cursor position before writing
163            curPosBfrWrite = this.getRow();
164
165            xmlWriter.writeXML(this, writer);
166        } else {
167            throw new SQLException(resBundle.handleGetObject("webrowsetimpl.invalidwr").toString());
168        }
169    }
170
171    /**
172     * Reads this <code>WebRowSet</code> object in its XML format.
173     *
174     * @throws SQLException if a database access error occurs
175     */
176    public void readXml(java.io.Reader reader) throws SQLException {
177        // %%%
178        // This will change to a XmlReader, which over-rides the default
179        // Xml that is used when a WRS is instantiated.
180        //WebRowSetXmlReader xmlReader = getXmlReader();
181        try {
182             if (reader != null) {
183                xmlReader.readXML(this, reader);
184
185                // Position is before the first row
186                // The cursor position is to be stored while serializng
187                // and deserializing the WebRowSet Object.
188                if(curPosBfrWrite == 0) {
189                   this.beforeFirst();
190                }
191
192                // Return the position back to place prior to callin writeXml
193                else {
194                   this.absolute(curPosBfrWrite);
195                }
196
197            } else {
198                throw new SQLException(resBundle.handleGetObject("webrowsetimpl.invalidrd").toString());
199            }
200        } catch (Exception e) {
201            throw new SQLException(e.getMessage());
202        }
203    }
204
205    // Stream based methods
206    /**
207     * Reads a stream based XML input to populate this <code>WebRowSet</code>
208     * object.
209     *
210     * @throws SQLException if a data source access error occurs
211     * @throws IOException if a IO exception occurs
212     */
213    public void readXml(java.io.InputStream iStream) throws SQLException, IOException {
214        if (iStream != null) {
215            xmlReader.readXML(this, iStream);
216
217            // Position is before the first row
218                // The cursor position is to be stored while serializng
219                // and deserializing the WebRowSet Object.
220                if(curPosBfrWrite == 0) {
221                   this.beforeFirst();
222                }
223
224                // Return the position back to place prior to callin writeXml
225                else {
226                   this.absolute(curPosBfrWrite);
227                }
228
229        } else {
230            throw new SQLException(resBundle.handleGetObject("webrowsetimpl.invalidrd").toString());
231        }
232    }
233
234    /**
235     * Writes this <code>WebRowSet</code> object to the given <code> OutputStream</code>
236     * object in XML format.
237     * Creates an output stream of the internal state and contents of a
238     * <code>WebRowSet</code> for XML proceessing
239     *
240     * @throws SQLException if a datasource access error occurs
241     * @throws IOException if an IO exception occurs
242     */
243    public void writeXml(java.io.OutputStream oStream) throws SQLException, IOException {
244        if (xmlWriter != null) {
245
246            // Store the cursor position before writing
247            curPosBfrWrite = this.getRow();
248
249            xmlWriter.writeXML(this, oStream);
250        } else {
251            throw new SQLException(resBundle.handleGetObject("webrowsetimpl.invalidwr").toString());
252        }
253
254    }
255
256    /**
257     * Populates this <code>WebRowSet</code> object with the
258     * data in the given <code>ResultSet</code> object and writes itself
259     * to the given <code>java.io.OutputStream</code> object in XML format.
260     * This includes the rowset's data,  properties, and metadata.
261     *
262     * @throws SQLException if a datasource access error occurs
263     * @throws IOException if an IO exception occurs
264     */
265    public void writeXml(ResultSet rs, java.io.OutputStream oStream) throws SQLException, IOException {
266            this.populate(rs);
267
268            // Store the cursor position before writing
269            curPosBfrWrite = this.getRow();
270
271            this.writeXml(oStream);
272    }
273
274    /**
275     * This method re populates the resBundle
276     * during the deserialization process
277     *
278     */
279    private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
280        // Default state initialization happens here
281        ois.defaultReadObject();
282        // Initialization of transient Res Bundle happens here .
283        try {
284           resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
285        } catch(IOException ioe) {
286            throw new RuntimeException(ioe);
287        }
288
289    }
290
291    static final long serialVersionUID = -8771775154092422943L;
292}
293