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
26package com.sun.rowset.internal;
27
28import com.sun.rowset.JdbcRowSetResourceBundle;
29import java.sql.*;
30import javax.sql.*;
31import java.io.*;
32import java.text.MessageFormat;
33import java.util.*;
34
35import javax.sql.rowset.*;
36import 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
43public 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}