Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.sql.rowset/share/classes/com/sun/rowset/internal/WebRowSetXmlWriter.java
40948 views
1
/*
2
* Copyright (c) 2003, 2012, 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} interface, which writes a
40
* {@code WebRowSet} 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} object to which this {@code WebRowSetXmlWriter}
47
* object will write when its {@code writeXML} method is called. The value
48
* for this field is set with the {@code java.io.Writer} object given
49
* as the second argument to the {@code writeXML} method.
50
*/
51
private transient java.io.Writer writer;
52
53
/**
54
* The {@code java.util.Stack} object that this {@code WebRowSetXmlWriter}
55
* object will use for storing the tags to be used for writing the calling
56
* {@code WebRowSet} object as an XML document.
57
*/
58
private java.util.Stack<String> 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} object as an XML document
73
* using the given {@code java.io.Writer} object. The XML document
74
* will include the {@code WebRowSet} 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} object that is
79
* referenced in the calling {@code WebRowSet} object's
80
* {@code xmlWriter} field. The {@code XmlWriter.writeXML}
81
* method passes to this method the arguments that were supplied to it.
82
*
83
* @param caller the {@code WebRowSet} object to be written; must
84
* be a rowset for which this {@code WebRowSetXmlWriter} object
85
* is the writer
86
* @param wrt the {@code java.io.Writer} object to which
87
* {@code caller} will be written
88
* @exception SQLException if a database access error occurs or
89
* this {@code WebRowSetXmlWriter} 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} object as an XML document
104
* using the given {@code java.io.OutputStream} object. The XML document
105
* will include the {@code WebRowSet} 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}
110
*
111
* This method is called by the {@code XmlWriter} object that is
112
* referenced in the calling {@code WebRowSet} object's
113
* {@code xmlWriter} field. The {@code XmlWriter.writeXML}
114
* method passes to this method the arguments that were supplied to it.
115
*
116
* @param caller the {@code WebRowSet} object to be written; must
117
* be a rowset for which this {@code WebRowSetXmlWriter} object
118
* is the writer
119
* @param oStream the {@code java.io.OutputStream} object to which
120
* {@code caller} will be written
121
* @throws SQLException if a database access error occurs or
122
* this {@code WebRowSetXmlWriter} 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
Map<String, Class<?>> typeMap = caller.getTypeMap();
209
if(typeMap != null) {
210
for(Map.Entry<String, Class<?>> mm : typeMap.entrySet()) {
211
propString("type", mm.getKey());
212
propString("class", mm.getValue().getName());
213
}
214
}
215
endSection("map");
216
217
propInteger("max-field-size", caller.getMaxFieldSize());
218
propInteger("max-rows", caller.getMaxRows());
219
propInteger("query-timeout", caller.getQueryTimeout());
220
propBoolean("read-only", caller.isReadOnly());
221
222
int itype = caller.getType();
223
String strType = "";
224
225
if(itype == 1003) {
226
strType = "ResultSet.TYPE_FORWARD_ONLY";
227
} else if(itype == 1004) {
228
strType = "ResultSet.TYPE_SCROLL_INSENSITIVE";
229
} else if(itype == 1005) {
230
strType = "ResultSet.TYPE_SCROLL_SENSITIVE";
231
}
232
233
propString("rowset-type", strType);
234
235
propBoolean("show-deleted", caller.getShowDeleted());
236
propString("table-name", caller.getTableName());
237
propString("url", caller.getUrl());
238
239
beginSection("sync-provider");
240
// Remove the string after "@xxxx"
241
// before writing it to the xml file.
242
String strProviderInstance = (caller.getSyncProvider()).toString();
243
String strProvider = strProviderInstance.substring(0, (caller.getSyncProvider()).toString().indexOf('@'));
244
245
propString("sync-provider-name", strProvider);
246
propString("sync-provider-vendor", "Oracle Corporation");
247
propString("sync-provider-version", "1.0");
248
propInteger("sync-provider-grade", caller.getSyncProvider().getProviderGrade());
249
propInteger("data-source-lock", caller.getSyncProvider().getDataSourceLock());
250
251
endSection("sync-provider");
252
253
} catch (SQLException ex) {
254
throw new java.io.IOException(MessageFormat.format(resBundle.handleGetObject("wrsxmlwriter.sqlex").toString(), ex.getMessage()));
255
}
256
257
endSection("properties");
258
}
259
260
/**
261
*
262
*
263
* @exception SQLException if a database access error occurs
264
*/
265
private void writeMetaData(WebRowSet caller) throws java.io.IOException {
266
int columnCount;
267
268
beginSection("metadata");
269
270
try {
271
272
ResultSetMetaData rsmd = caller.getMetaData();
273
columnCount = rsmd.getColumnCount();
274
propInteger("column-count", columnCount);
275
276
for (int colIndex = 1; colIndex <= columnCount; colIndex++) {
277
beginSection("column-definition");
278
279
propInteger("column-index", colIndex);
280
propBoolean("auto-increment", rsmd.isAutoIncrement(colIndex));
281
propBoolean("case-sensitive", rsmd.isCaseSensitive(colIndex));
282
propBoolean("currency", rsmd.isCurrency(colIndex));
283
propInteger("nullable", rsmd.isNullable(colIndex));
284
propBoolean("signed", rsmd.isSigned(colIndex));
285
propBoolean("searchable", rsmd.isSearchable(colIndex));
286
propInteger("column-display-size",rsmd.getColumnDisplaySize(colIndex));
287
propString("column-label", rsmd.getColumnLabel(colIndex));
288
propString("column-name", rsmd.getColumnName(colIndex));
289
propString("schema-name", rsmd.getSchemaName(colIndex));
290
propInteger("column-precision", rsmd.getPrecision(colIndex));
291
propInteger("column-scale", rsmd.getScale(colIndex));
292
propString("table-name", rsmd.getTableName(colIndex));
293
propString("catalog-name", rsmd.getCatalogName(colIndex));
294
propInteger("column-type", rsmd.getColumnType(colIndex));
295
propString("column-type-name", rsmd.getColumnTypeName(colIndex));
296
297
endSection("column-definition");
298
}
299
} catch (SQLException ex) {
300
throw new java.io.IOException(MessageFormat.format(resBundle.handleGetObject("wrsxmlwriter.sqlex").toString(), ex.getMessage()));
301
}
302
303
endSection("metadata");
304
}
305
306
/**
307
*
308
*
309
* @exception SQLException if a database access error occurs
310
*/
311
private void writeData(WebRowSet caller) throws java.io.IOException {
312
ResultSet rs;
313
314
try {
315
ResultSetMetaData rsmd = caller.getMetaData();
316
int columnCount = rsmd.getColumnCount();
317
int i;
318
319
beginSection("data");
320
321
caller.beforeFirst();
322
caller.setShowDeleted(true);
323
while (caller.next()) {
324
if (caller.rowDeleted() && caller.rowInserted()) {
325
beginSection("modifyRow");
326
} else if (caller.rowDeleted()) {
327
beginSection("deleteRow");
328
} else if (caller.rowInserted()) {
329
beginSection("insertRow");
330
} else {
331
beginSection("currentRow");
332
}
333
334
for (i = 1; i <= columnCount; i++) {
335
if (caller.columnUpdated(i)) {
336
rs = caller.getOriginalRow();
337
rs.next();
338
beginTag("columnValue");
339
writeValue(i, (RowSet)rs);
340
endTag("columnValue");
341
beginTag("updateRow");
342
writeValue(i, caller);
343
endTag("updateRow");
344
} else {
345
beginTag("columnValue");
346
writeValue(i, caller);
347
endTag("columnValue");
348
}
349
}
350
351
endSection(); // this is unchecked
352
}
353
endSection("data");
354
} catch (SQLException ex) {
355
throw new java.io.IOException(MessageFormat.format(resBundle.handleGetObject("wrsxmlwriter.sqlex").toString(), ex.getMessage()));
356
}
357
}
358
359
private void writeValue(int idx, RowSet caller) throws java.io.IOException {
360
try {
361
int type = caller.getMetaData().getColumnType(idx);
362
363
switch (type) {
364
case java.sql.Types.BIT:
365
case java.sql.Types.BOOLEAN:
366
boolean b = caller.getBoolean(idx);
367
if (caller.wasNull())
368
writeNull();
369
else
370
writeBoolean(b);
371
break;
372
case java.sql.Types.TINYINT:
373
case java.sql.Types.SMALLINT:
374
short s = caller.getShort(idx);
375
if (caller.wasNull())
376
writeNull();
377
else
378
writeShort(s);
379
break;
380
case java.sql.Types.INTEGER:
381
int i = caller.getInt(idx);
382
if (caller.wasNull())
383
writeNull();
384
else
385
writeInteger(i);
386
break;
387
case java.sql.Types.BIGINT:
388
long l = caller.getLong(idx);
389
if (caller.wasNull())
390
writeNull();
391
else
392
writeLong(l);
393
break;
394
case java.sql.Types.REAL:
395
case java.sql.Types.FLOAT:
396
float f = caller.getFloat(idx);
397
if (caller.wasNull())
398
writeNull();
399
else
400
writeFloat(f);
401
break;
402
case java.sql.Types.DOUBLE:
403
double d = caller.getDouble(idx);
404
if (caller.wasNull())
405
writeNull();
406
else
407
writeDouble(d);
408
break;
409
case java.sql.Types.NUMERIC:
410
case java.sql.Types.DECIMAL:
411
writeBigDecimal(caller.getBigDecimal(idx));
412
break;
413
case java.sql.Types.BINARY:
414
case java.sql.Types.VARBINARY:
415
case java.sql.Types.LONGVARBINARY:
416
break;
417
case java.sql.Types.DATE:
418
java.sql.Date date = caller.getDate(idx);
419
if (caller.wasNull())
420
writeNull();
421
else
422
writeLong(date.getTime());
423
break;
424
case java.sql.Types.TIME:
425
java.sql.Time time = caller.getTime(idx);
426
if (caller.wasNull())
427
writeNull();
428
else
429
writeLong(time.getTime());
430
break;
431
case java.sql.Types.TIMESTAMP:
432
java.sql.Timestamp ts = caller.getTimestamp(idx);
433
if (caller.wasNull())
434
writeNull();
435
else
436
writeLong(ts.getTime());
437
break;
438
case java.sql.Types.CHAR:
439
case java.sql.Types.VARCHAR:
440
case java.sql.Types.LONGVARCHAR:
441
writeStringData(caller.getString(idx));
442
break;
443
default:
444
System.out.println(resBundle.handleGetObject("wsrxmlwriter.notproper").toString());
445
//Need to take care of BLOB, CLOB, Array, Ref here
446
}
447
} catch (SQLException ex) {
448
throw new java.io.IOException(resBundle.handleGetObject("wrsxmlwriter.failedwrite").toString()+ ex.getMessage());
449
}
450
}
451
452
/*
453
* This begins a new tag with a indent
454
*
455
*/
456
private void beginSection(String tag) throws java.io.IOException {
457
// store the current tag
458
setTag(tag);
459
460
writeIndent(stack.size());
461
462
// write it out
463
writer.write("<" + tag + ">\n");
464
}
465
466
/*
467
* This closes a tag started by beginTag with a indent
468
*
469
*/
470
private void endSection(String tag) throws java.io.IOException {
471
writeIndent(stack.size());
472
473
String beginTag = getTag();
474
475
if(beginTag.indexOf("webRowSet") != -1) {
476
beginTag ="webRowSet";
477
}
478
479
if (tag.equals(beginTag) ) {
480
// get the current tag and write it out
481
writer.write("</" + beginTag + ">\n");
482
} else {
483
;
484
}
485
writer.flush();
486
}
487
488
private void endSection() throws java.io.IOException {
489
writeIndent(stack.size());
490
491
// get the current tag and write it out
492
String beginTag = getTag();
493
writer.write("</" + beginTag + ">\n");
494
495
writer.flush();
496
}
497
498
private void beginTag(String tag) throws java.io.IOException {
499
// store the current tag
500
setTag(tag);
501
502
writeIndent(stack.size());
503
504
// write tag out
505
writer.write("<" + tag + ">");
506
}
507
508
private void endTag(String tag) throws java.io.IOException {
509
String beginTag = getTag();
510
if (tag.equals(beginTag)) {
511
// get the current tag and write it out
512
writer.write("</" + beginTag + ">\n");
513
} else {
514
;
515
}
516
writer.flush();
517
}
518
519
private void emptyTag(String tag) throws java.io.IOException {
520
// write an emptyTag
521
writer.write("<" + tag + "/>");
522
}
523
524
private void setTag(String tag) {
525
// add the tag to stack
526
stack.push(tag);
527
}
528
529
private String getTag() {
530
return stack.pop();
531
}
532
533
private void writeNull() throws java.io.IOException {
534
emptyTag("null");
535
}
536
537
private void writeStringData(String s) throws java.io.IOException {
538
if (s == null) {
539
writeNull();
540
} else if (s.isEmpty()) {
541
writeEmptyString();
542
} else {
543
544
s = processSpecialCharacters(s);
545
546
writer.write(s);
547
}
548
}
549
550
private void writeString(String s) throws java.io.IOException {
551
if (s != null) {
552
writer.write(s);
553
} else {
554
writeNull();
555
}
556
}
557
558
559
private void writeShort(short s) throws java.io.IOException {
560
writer.write(Short.toString(s));
561
}
562
563
private void writeLong(long l) throws java.io.IOException {
564
writer.write(Long.toString(l));
565
}
566
567
private void writeInteger(int i) throws java.io.IOException {
568
writer.write(Integer.toString(i));
569
}
570
571
private void writeBoolean(boolean b) throws java.io.IOException {
572
writer.write(Boolean.valueOf(b).toString());
573
}
574
575
private void writeFloat(float f) throws java.io.IOException {
576
writer.write(Float.toString(f));
577
}
578
579
private void writeDouble(double d) throws java.io.IOException {
580
writer.write(Double.toString(d));
581
}
582
583
private void writeBigDecimal(java.math.BigDecimal bd) throws java.io.IOException {
584
if (bd != null)
585
writer.write(bd.toString());
586
else
587
emptyTag("null");
588
}
589
590
private void writeIndent(int tabs) throws java.io.IOException {
591
// indent...
592
for (int i = 1; i < tabs; i++) {
593
writer.write(" ");
594
}
595
}
596
597
private void propString(String tag, String s) throws java.io.IOException {
598
beginTag(tag);
599
writeString(s);
600
endTag(tag);
601
}
602
603
private void propInteger(String tag, int i) throws java.io.IOException {
604
beginTag(tag);
605
writeInteger(i);
606
endTag(tag);
607
}
608
609
private void propBoolean(String tag, boolean b) throws java.io.IOException {
610
beginTag(tag);
611
writeBoolean(b);
612
endTag(tag);
613
}
614
615
private void writeEmptyString() throws java.io.IOException {
616
emptyTag("emptyString");
617
}
618
/**
619
* Purely for code coverage purposes..
620
*/
621
public boolean writeData(RowSetInternal caller) {
622
return false;
623
}
624
625
626
/**
627
* This function has been added for the processing of special characters
628
* lik <,>,'," and & in the data to be serialized. These have to be taken
629
* of specifically or else there will be parsing error while trying to read
630
* the contents of the XML file.
631
**/
632
633
private String processSpecialCharacters(String s) {
634
635
if(s == null) {
636
return null;
637
}
638
char []charStr = s.toCharArray();
639
String specialStr = "";
640
641
for(int i = 0; i < charStr.length; i++) {
642
if(charStr[i] == '&') {
643
specialStr = specialStr.concat("&amp;");
644
} else if(charStr[i] == '<') {
645
specialStr = specialStr.concat("&lt;");
646
} else if(charStr[i] == '>') {
647
specialStr = specialStr.concat("&gt;");
648
} else if(charStr[i] == '\'') {
649
specialStr = specialStr.concat("&apos;");
650
} else if(charStr[i] == '\"') {
651
specialStr = specialStr.concat("&quot;");
652
} else {
653
specialStr = specialStr.concat(String.valueOf(charStr[i]));
654
}
655
}
656
657
s = specialStr;
658
return s;
659
}
660
661
662
/**
663
* This method re populates the resBundle
664
* during the deserialization process
665
*
666
*/
667
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
668
// Default state initialization happens here
669
ois.defaultReadObject();
670
// Initialization of transient Res Bundle happens here .
671
try {
672
resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
673
} catch(IOException ioe) {
674
throw new RuntimeException(ioe);
675
}
676
677
}
678
679
static final long serialVersionUID = 7163134986189677641L;
680
}
681
682