History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/com/sun/rowset/internal/WebRowSetXmlWriter.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/rowset/internal/WebRowSetXmlWriter.java+685−0
@@ -0,0 +1,685 @@
1+/*
2+ * Copyright (c) 2003, 2010, 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+
26+package com.sun.rowset.internal;
27+
28+import com.sun.rowset.JdbcRowSetResourceBundle;
29+import java.sql.*;
30+import javax.sql.*;
31+import java.io.*;
32+import java.text.MessageFormat;
33+import java.util.*;
34+
35+import javax.sql.rowset.*;
36+import javax.sql.rowset.spi.*;
37+
38+/**
39+ * An implementation of the <code>XmlWriter</code> interface, which writes a
40+ * <code>WebRowSet</code> object to an output stream as an XML document.
41+ */
42+
43+public class WebRowSetXmlWriter implements XmlWriter, Serializable {
44+
45+ /**
46+ * The <code>java.io.Writer</code> object to which this <code>WebRowSetXmlWriter</code>
47+ * object will write when its <code>writeXML</code> method is called. The value
48+ * for this field is set with the <code>java.io.Writer</code> object given
49+ * as the second argument to the <code>writeXML</code> method.
50+ */
51+ private java.io.Writer writer;
52+
53+ /**
54+ * The <code>java.util.Stack</code> object that this <code>WebRowSetXmlWriter</code>
55+ * object will use for storing the tags to be used for writing the calling
56+ * <code>WebRowSet</code> object as an XML document.
57+ */
58+ private java.util.Stack stack;
59+
60+ private JdbcRowSetResourceBundle resBundle;
61+
62+ public WebRowSetXmlWriter() {
63+
64+ try {
65+ resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
66+ } catch(IOException ioe) {
67+ throw new RuntimeException(ioe);
68+ }
69+ }
70+
71+ /**
72+ * Writes the given <code>WebRowSet</code> object as an XML document
73+ * using the given <code>java.io.Writer</code> object. The XML document
74+ * will include the <code>WebRowSet</code> object's data, metadata, and
75+ * properties. If a data value has been updated, that information is also
76+ * included.
77+ * <P>
78+ * This method is called by the <code>XmlWriter</code> object that is
79+ * referenced in the calling <code>WebRowSet</code> object's
80+ * <code>xmlWriter</code> field. The <code>XmlWriter.writeXML</code>
81+ * method passes to this method the arguments that were supplied to it.
82+ *
83+ * @param caller the <code>WebRowSet</code> object to be written; must
84+ * be a rowset for which this <code>WebRowSetXmlWriter</code> object
85+ * is the writer
86+ * @param wrt the <code>java.io.Writer</code> object to which
87+ * <code>caller</code> will be written
88+ * @exception SQLException if a database access error occurs or
89+ * this <code>WebRowSetXmlWriter</code> object is not the writer
90+ * for the given rowset
91+ * @see XmlWriter#writeXML
92+ */
93+ public void writeXML(WebRowSet caller, java.io.Writer wrt)
94+ throws SQLException {
95+
96+ // create a new stack for tag checking.
97+ stack = new java.util.Stack();
98+ writer = wrt;
99+ writeRowSet(caller);
100+ }
101+
102+ /**
103+ * Writes the given <code>WebRowSet</code> object as an XML document
104+ * using the given <code>java.io.OutputStream</code> object. The XML document
105+ * will include the <code>WebRowSet</code> object's data, metadata, and
106+ * properties. If a data value has been updated, that information is also
107+ * included.
108+ * <P>
109+ * Using stream is a faster way than using <code>java.io.Writer<code/>
110+ *
111+ * This method is called by the <code>XmlWriter</code> object that is
112+ * referenced in the calling <code>WebRowSet</code> object's
113+ * <code>xmlWriter</code> field. The <code>XmlWriter.writeXML</code>
114+ * method passes to this method the arguments that were supplied to it.
115+ *
116+ * @param caller the <code>WebRowSet</code> object to be written; must
117+ * be a rowset for which this <code>WebRowSetXmlWriter</code> object
118+ * is the writer
119+ * @param oStream the <code>java.io.OutputStream</code> object to which
120+ * <code>caller</code> will be written
121+ * @throws SQLException if a database access error occurs or
122+ * this <code>WebRowSetXmlWriter</code> object is not the writer
123+ * for the given rowset
124+ * @see XmlWriter#writeXML
125+ */
126+ public void writeXML(WebRowSet caller, java.io.OutputStream oStream)
127+ throws SQLException {
128+
129+ // create a new stack for tag checking.
130+ stack = new java.util.Stack();
131+ writer = new OutputStreamWriter(oStream);
132+ writeRowSet(caller);
133+ }
134+
135+ /**
136+ *
137+ *
138+ * @exception SQLException if a database access error occurs
139+ */
140+ private void writeRowSet(WebRowSet caller) throws SQLException {
141+
142+ try {
143+
144+ startHeader();
145+
146+ writeProperties(caller);
147+ writeMetaData(caller);
148+ writeData(caller);
149+
150+ endHeader();
151+
152+ } catch (java.io.IOException ex) {
153+ throw new SQLException(MessageFormat.format(resBundle.handleGetObject("wrsxmlwriter.ioex").toString(), ex.getMessage()));
154+ }
155+ }
156+
157+ private void startHeader() throws java.io.IOException {
158+
159+ setTag("webRowSet");
160+ writer.write("<?xml version=\"1.0\"?>\n");
161+ writer.write("<webRowSet xmlns=\"http://java.sun.com/xml/ns/jdbc\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"\n");
162+ writer.write("xsi:schemaLocation=\"http://java.sun.com/xml/ns/jdbc http://java.sun.com/xml/ns/jdbc/webrowset.xsd\">\n");
163+ }
164+
165+ private void endHeader() throws java.io.IOException {
166+ endTag("webRowSet");
167+ }
168+
169+ /**
170+ *
171+ *
172+ * @exception SQLException if a database access error occurs
173+ */
174+ private void writeProperties(WebRowSet caller) throws java.io.IOException {
175+
176+ beginSection("properties");
177+
178+ try {
179+ propString("command", processSpecialCharacters(caller.getCommand()));
180+ propInteger("concurrency", caller.getConcurrency());
181+ propString("datasource", caller.getDataSourceName());
182+ propBoolean("escape-processing",
183+ caller.getEscapeProcessing());
184+
185+ try {
186+ propInteger("fetch-direction", caller.getFetchDirection());
187+ } catch(SQLException sqle) {
188+ // it may be the case that fetch direction has not been set
189+ // fetchDir == 0
190+ // in that case it will throw a SQLException.
191+ // To avoid that catch it here
192+ }
193+
194+ propInteger("fetch-size", caller.getFetchSize());
195+ propInteger("isolation-level",
196+ caller.getTransactionIsolation());
197+
198+ beginSection("key-columns");
199+
200+ int[] kc = caller.getKeyColumns();
201+ for (int i = 0; kc != null && i < kc.length; i++)
202+ propInteger("column", kc[i]);
203+
204+ endSection("key-columns");
205+
206+ //Changed to beginSection and endSection for maps for proper indentation
207+ beginSection("map");
208+ java.util.Map typeMap = caller.getTypeMap();
209+ if (typeMap != null) {
210+ Iterator i = typeMap.keySet().iterator();
211+ Class c;
212+ String type;
213+ while (i.hasNext()) {
214+ type = (String)i.next();
215+ c = (Class)typeMap.get(type);
216+ propString("type", type);
217+ propString("class", c.getName());
218+ }
219+ }
220+ endSection("map");
221+
222+ propInteger("max-field-size", caller.getMaxFieldSize());
223+ propInteger("max-rows", caller.getMaxRows());
224+ propInteger("query-timeout", caller.getQueryTimeout());
225+ propBoolean("read-only", caller.isReadOnly());
226+
227+ int itype = caller.getType();
228+ String strType = "";
229+
230+ if(itype == 1003) {
231+ strType = "ResultSet.TYPE_FORWARD_ONLY";
232+ } else if(itype == 1004) {
233+ strType = "ResultSet.TYPE_SCROLL_INSENSITIVE";
234+ } else if(itype == 1005) {
235+ strType = "ResultSet.TYPE_SCROLL_SENSITIVE";
236+ }
237+
238+ propString("rowset-type", strType);
239+
240+ propBoolean("show-deleted", caller.getShowDeleted());
241+ propString("table-name", caller.getTableName());
242+ propString("url", caller.getUrl());
243+
244+ beginSection("sync-provider");
245+ // Remove the string after "@xxxx"
246+ // before writing it to the xml file.
247+ String strProviderInstance = (caller.getSyncProvider()).toString();
248+ String strProvider = strProviderInstance.substring(0, (caller.getSyncProvider()).toString().indexOf("@"));
249+
250+ propString("sync-provider-name", strProvider);
251+ propString("sync-provider-vendor", "Oracle Corporation");
252+ propString("sync-provider-version", "1.0");
253+ propInteger("sync-provider-grade", caller.getSyncProvider().getProviderGrade());
254+ propInteger("data-source-lock", caller.getSyncProvider().getDataSourceLock());
255+
256+ endSection("sync-provider");
257+
258+ } catch (SQLException ex) {
259+ throw new java.io.IOException(MessageFormat.format(resBundle.handleGetObject("wrsxmlwriter.sqlex").toString(), ex.getMessage()));
260+ }
261+
262+ endSection("properties");
263+ }
264+
265+ /**
266+ *
267+ *
268+ * @exception SQLException if a database access error occurs
269+ */
270+ private void writeMetaData(WebRowSet caller) throws java.io.IOException {
271+ int columnCount;
272+
273+ beginSection("metadata");
274+
275+ try {
276+
277+ ResultSetMetaData rsmd = caller.getMetaData();
278+ columnCount = rsmd.getColumnCount();
279+ propInteger("column-count", columnCount);
280+
281+ for (int colIndex = 1; colIndex <= columnCount; colIndex++) {
282+ beginSection("column-definition");
283+
284+ propInteger("column-index", colIndex);
285+ propBoolean("auto-increment", rsmd.isAutoIncrement(colIndex));
286+ propBoolean("case-sensitive", rsmd.isCaseSensitive(colIndex));
287+ propBoolean("currency", rsmd.isCurrency(colIndex));
288+ propInteger("nullable", rsmd.isNullable(colIndex));
289+ propBoolean("signed", rsmd.isSigned(colIndex));
290+ propBoolean("searchable", rsmd.isSearchable(colIndex));
291+ propInteger("column-display-size",rsmd.getColumnDisplaySize(colIndex));
292+ propString("column-label", rsmd.getColumnLabel(colIndex));
293+ propString("column-name", rsmd.getColumnName(colIndex));
294+ propString("schema-name", rsmd.getSchemaName(colIndex));
295+ propInteger("column-precision", rsmd.getPrecision(colIndex));
296+ propInteger("column-scale", rsmd.getScale(colIndex));
297+ propString("table-name", rsmd.getTableName(colIndex));
298+ propString("catalog-name", rsmd.getCatalogName(colIndex));
299+ propInteger("column-type", rsmd.getColumnType(colIndex));
300+ propString("column-type-name", rsmd.getColumnTypeName(colIndex));
301+
302+ endSection("column-definition");
303+ }
304+ } catch (SQLException ex) {
305+ throw new java.io.IOException(MessageFormat.format(resBundle.handleGetObject("wrsxmlwriter.sqlex").toString(), ex.getMessage()));
306+ }
307+
308+ endSection("metadata");
309+ }
310+
311+ /**
312+ *
313+ *
314+ * @exception SQLException if a database access error occurs
315+ */
316+ private void writeData(WebRowSet caller) throws java.io.IOException {
317+ ResultSet rs;
318+
319+ try {
320+ ResultSetMetaData rsmd = caller.getMetaData();
321+ int columnCount = rsmd.getColumnCount();
322+ int i;
323+
324+ beginSection("data");
325+
326+ caller.beforeFirst();
327+ caller.setShowDeleted(true);
328+ while (caller.next()) {
329+ if (caller.rowDeleted() && caller.rowInserted()) {
330+ beginSection("modifyRow");
331+ } else if (caller.rowDeleted()) {
332+ beginSection("deleteRow");
333+ } else if (caller.rowInserted()) {
334+ beginSection("insertRow");
335+ } else {
336+ beginSection("currentRow");
337+ }
338+
339+ for (i = 1; i <= columnCount; i++) {
340+ if (caller.columnUpdated(i)) {
341+ rs = caller.getOriginalRow();
342+ rs.next();
343+ beginTag("columnValue");
344+ writeValue(i, (RowSet)rs);
345+ endTag("columnValue");
346+ beginTag("updateRow");
347+ writeValue(i, caller);
348+ endTag("updateRow");
349+ } else {
350+ beginTag("columnValue");
351+ writeValue(i, caller);
352+ endTag("columnValue");
353+ }
354+ }
355+
356+ endSection(); // this is unchecked
357+ }
358+ endSection("data");
359+ } catch (SQLException ex) {
360+ throw new java.io.IOException(MessageFormat.format(resBundle.handleGetObject("wrsxmlwriter.sqlex").toString(), ex.getMessage()));
361+ }
362+ }
363+
364+ private void writeValue(int idx, RowSet caller) throws java.io.IOException {
365+ try {
366+ int type = caller.getMetaData().getColumnType(idx);
367+
368+ switch (type) {
369+ case java.sql.Types.BIT:
370+ case java.sql.Types.BOOLEAN:
371+ boolean b = caller.getBoolean(idx);
372+ if (caller.wasNull())
373+ writeNull();
374+ else
375+ writeBoolean(b);
376+ break;
377+ case java.sql.Types.TINYINT:
378+ case java.sql.Types.SMALLINT:
379+ short s = caller.getShort(idx);
380+ if (caller.wasNull())
381+ writeNull();
382+ else
383+ writeShort(s);
384+ break;
385+ case java.sql.Types.INTEGER:
386+ int i = caller.getInt(idx);
387+ if (caller.wasNull())
388+ writeNull();
389+ else
390+ writeInteger(i);
391+ break;
392+ case java.sql.Types.BIGINT:
393+ long l = caller.getLong(idx);
394+ if (caller.wasNull())
395+ writeNull();
396+ else
397+ writeLong(l);
398+ break;
399+ case java.sql.Types.REAL:
400+ case java.sql.Types.FLOAT:
401+ float f = caller.getFloat(idx);
402+ if (caller.wasNull())
403+ writeNull();
404+ else
405+ writeFloat(f);
406+ break;
407+ case java.sql.Types.DOUBLE:
408+ double d = caller.getDouble(idx);
409+ if (caller.wasNull())
410+ writeNull();
411+ else
412+ writeDouble(d);
413+ break;
414+ case java.sql.Types.NUMERIC:
415+ case java.sql.Types.DECIMAL:
416+ writeBigDecimal(caller.getBigDecimal(idx));
417+ break;
418+ case java.sql.Types.BINARY:
419+ case java.sql.Types.VARBINARY:
420+ case java.sql.Types.LONGVARBINARY:
421+ break;
422+ case java.sql.Types.DATE:
423+ java.sql.Date date = caller.getDate(idx);
424+ if (caller.wasNull())
425+ writeNull();
426+ else
427+ writeLong(date.getTime());
428+ break;
429+ case java.sql.Types.TIME:
430+ java.sql.Time time = caller.getTime(idx);
431+ if (caller.wasNull())
432+ writeNull();
433+ else
434+ writeLong(time.getTime());
435+ break;
436+ case java.sql.Types.TIMESTAMP:
437+ java.sql.Timestamp ts = caller.getTimestamp(idx);
438+ if (caller.wasNull())
439+ writeNull();
440+ else
441+ writeLong(ts.getTime());
442+ break;
443+ case java.sql.Types.CHAR:
444+ case java.sql.Types.VARCHAR:
445+ case java.sql.Types.LONGVARCHAR:
446+ writeStringData(caller.getString(idx));
447+ break;
448+ default:
449+ System.out.println(resBundle.handleGetObject("wsrxmlwriter.notproper").toString());
450+ //Need to take care of BLOB, CLOB, Array, Ref here
451+ }
452+ } catch (SQLException ex) {
453+ throw new java.io.IOException(resBundle.handleGetObject("wrsxmlwriter.failedwrite").toString()+ ex.getMessage());
454+ }
455+ }
456+
457+ /*
458+ * This begins a new tag with a indent
459+ *
460+ */
461+ private void beginSection(String tag) throws java.io.IOException {
462+ // store the current tag
463+ setTag(tag);
464+
465+ writeIndent(stack.size());
466+
467+ // write it out
468+ writer.write("<" + tag + ">\n");
469+ }
470+
471+ /*
472+ * This closes a tag started by beginTag with a indent
473+ *
474+ */
475+ private void endSection(String tag) throws java.io.IOException {
476+ writeIndent(stack.size());
477+
478+ String beginTag = getTag();
479+
480+ if(beginTag.indexOf("webRowSet") != -1) {
481+ beginTag ="webRowSet";
482+ }
483+
484+ if (tag.equals(beginTag) ) {
485+ // get the current tag and write it out
486+ writer.write("</" + beginTag + ">\n");
487+ } else {
488+ ;
489+ }
490+ writer.flush();
491+ }
492+
493+ private void endSection() throws java.io.IOException {
494+ writeIndent(stack.size());
495+
496+ // get the current tag and write it out
497+ String beginTag = getTag();
498+ writer.write("</" + beginTag + ">\n");
499+
500+ writer.flush();
501+ }
502+
503+ private void beginTag(String tag) throws java.io.IOException {
504+ // store the current tag
505+ setTag(tag);
506+
507+ writeIndent(stack.size());
508+
509+ // write tag out
510+ writer.write("<" + tag + ">");
511+ }
512+
513+ private void endTag(String tag) throws java.io.IOException {
514+ String beginTag = getTag();
515+ if (tag.equals(beginTag)) {
516+ // get the current tag and write it out
517+ writer.write("</" + beginTag + ">\n");
518+ } else {
519+ ;
520+ }
521+ writer.flush();
522+ }
523+
524+ private void emptyTag(String tag) throws java.io.IOException {
525+ // write an emptyTag
526+ writer.write("<" + tag + "/>");
527+ }
528+
529+ private void setTag(String tag) {
530+ // add the tag to stack
531+ stack.push(tag);
532+ }
533+
534+ private String getTag() {
535+ return (String)stack.pop();
536+ }
537+
538+ private void writeNull() throws java.io.IOException {
539+ emptyTag("null");
540+ }
541+
542+ private void writeStringData(String s) throws java.io.IOException {
543+ if (s == null) {
544+ writeNull();
545+ } else if (s.equals("")) {
546+ writeEmptyString();
547+ } else {
548+
549+ s = processSpecialCharacters(s);
550+
551+ writer.write(s);
552+ }
553+ }
554+
555+ private void writeString(String s) throws java.io.IOException {
556+ if (s != null) {
557+ writer.write(s);
558+ } else {
559+ writeNull();
560+ }
561+ }
562+
563+
564+ private void writeShort(short s) throws java.io.IOException {
565+ writer.write(Short.toString(s));
566+ }
567+
568+ private void writeLong(long l) throws java.io.IOException {
569+ writer.write(Long.toString(l));
570+ }
571+
572+ private void writeInteger(int i) throws java.io.IOException {
573+ writer.write(Integer.toString(i));
574+ }
575+
576+ private void writeBoolean(boolean b) throws java.io.IOException {
577+ writer.write(Boolean.valueOf(b).toString());
578+ }
579+
580+ private void writeFloat(float f) throws java.io.IOException {
581+ writer.write(Float.toString(f));
582+ }
583+
584+ private void writeDouble(double d) throws java.io.IOException {
585+ writer.write(Double.toString(d));
586+ }
587+
588+ private void writeBigDecimal(java.math.BigDecimal bd) throws java.io.IOException {
589+ if (bd != null)
590+ writer.write(bd.toString());
591+ else
592+ emptyTag("null");
593+ }
594+
595+ private void writeIndent(int tabs) throws java.io.IOException {
596+ // indent...
597+ for (int i = 1; i < tabs; i++) {
598+ writer.write(" ");
599+ }
600+ }
601+
602+ private void propString(String tag, String s) throws java.io.IOException {
603+ beginTag(tag);
604+ writeString(s);
605+ endTag(tag);
606+ }
607+
608+ private void propInteger(String tag, int i) throws java.io.IOException {
609+ beginTag(tag);
610+ writeInteger(i);
611+ endTag(tag);
612+ }
613+
614+ private void propBoolean(String tag, boolean b) throws java.io.IOException {
615+ beginTag(tag);
616+ writeBoolean(b);
617+ endTag(tag);
618+ }
619+
620+ private void writeEmptyString() throws java.io.IOException {
621+ emptyTag("emptyString");
622+ }
623+ /**
624+ * Purely for code coverage purposes..
625+ */
626+ public boolean writeData(RowSetInternal caller) {
627+ return false;
628+ }
629+
630+
631+ /**
632+ * This function has been added for the processing of special characters
633+ * lik <,>,'," and & in the data to be serialized. These have to be taken
634+ * of specifically or else there will be parsing error while trying to read
635+ * the contents of the XML file.
636+ **/
637+
638+ private String processSpecialCharacters(String s) {
639+
640+ if(s == null) {
641+ return null;
642+ }
643+ char []charStr = s.toCharArray();
644+ String specialStr = "";
645+
646+ for(int i = 0; i < charStr.length; i++) {
647+ if(charStr[i] == '&') {
648+ specialStr = specialStr.concat("&amp;");
649+ } else if(charStr[i] == '<') {
650+ specialStr = specialStr.concat("&lt;");
651+ } else if(charStr[i] == '>') {
652+ specialStr = specialStr.concat("&gt;");
653+ } else if(charStr[i] == '\'') {
654+ specialStr = specialStr.concat("&apos;");
655+ } else if(charStr[i] == '\"') {
656+ specialStr = specialStr.concat("&quot;");
657+ } else {
658+ specialStr = specialStr.concat(String.valueOf(charStr[i]));
659+ }
660+ }
661+
662+ s = specialStr;
663+ return s;
664+ }
665+
666+
667+ /**
668+ * This method re populates the resBundle
669+ * during the deserialization process
670+ *
671+ */
672+ private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
673+ // Default state initialization happens here
674+ ois.defaultReadObject();
675+ // Initialization of transient Res Bundle happens here .
676+ try {
677+ resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
678+ } catch(IOException ioe) {
679+ throw new RuntimeException(ioe);
680+ }
681+
682+ }
683+
684+ static final long serialVersionUID = 7163134986189677641L;
685+}