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/XmlReaderContentHandler.java
40948 views
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
26
package com.sun.rowset.internal;
27
28
import java.util.*;
29
30
import org.xml.sax.*;
31
import org.xml.sax.helpers.*;
32
33
import java.sql.*;
34
import javax.sql.*;
35
36
import javax.sql.rowset.*;
37
import com.sun.rowset.*;
38
import java.io.IOException;
39
import java.text.MessageFormat;
40
41
/**
42
* The document handler that receives parse events that an XML parser sends while it
43
* is parsing an XML document representing a <code>WebRowSet</code> object. The
44
* parser sends strings to this <code>XmlReaderContentHandler</code> and then uses
45
* these strings as arguments for the <code>XmlReaderContentHandler</code> methods
46
* it invokes. The final goal of the SAX parser working with an
47
* <code>XmlReaderContentHandler</code> object is to read an XML document that represents
48
* a <code>RowSet</code> object.
49
* <P>
50
* A rowset consists of its properties, metadata, and data values. An XML document
51
* representating a rowset includes the values in these three categories along with
52
* appropriate XML tags to identify them. It also includes a top-level XML tag for
53
* the rowset and three section tags identifying the three categories of values.
54
* <P>
55
* The tags in an XML document are hierarchical.
56
* This means that the top-level tag, <code>RowSet</code>, is
57
* followed by the three sections with appropriate tags, which are in turn each
58
* followed by their constituent elements. For example, the <code>properties</code>
59
* element will be followed by an element for each of the properties listed in
60
* in this <code>XmlReaderContentHandler</code> object's <code>properties</code>
61
* field. The content of the other two fields, <code>colDef</code>, which lists
62
* the rowset's metadata elements, and <code>data</code>, which lists the rowset's data
63
* elements, are handled similarly .
64
* <P>
65
* This implementation of <code>XmlReaderContentHandler</code> provides the means for the
66
* parser to determine which elements need to have a value set and then to set
67
* those values. The methods in this class are all called by the parser; an
68
* application programmer never calls them directly.
69
*
70
*/
71
72
public class XmlReaderContentHandler extends DefaultHandler {
73
74
private HashMap <String, Integer> propMap;
75
private HashMap <String, Integer> colDefMap;
76
private HashMap <String, Integer> dataMap;
77
78
private HashMap<String,Class<?>> typeMap;
79
80
private Vector<Object[]> updates;
81
private Vector<String> keyCols;
82
83
private String columnValue;
84
private String propertyValue;
85
private String metaDataValue;
86
87
private int tag;
88
private int state;
89
90
private WebRowSetImpl rs;
91
private boolean nullVal;
92
private boolean emptyStringVal;
93
private RowSetMetaData md;
94
private int idx;
95
private String lastval;
96
private String Key_map;
97
private String Value_map;
98
private String tempStr;
99
private String tempUpdate;
100
private String tempCommand;
101
private Object [] upd;
102
103
/**
104
* A list of the properties for a rowset. There is a constant defined to
105
* correspond to each of these properties so that a <code>HashMap</code>
106
* object can be created to map the properties, which are strings, to
107
* the constants, which are integers.
108
*/
109
private String [] properties = {"command", "concurrency", "datasource",
110
"escape-processing", "fetch-direction", "fetch-size",
111
"isolation-level", "key-columns", "map",
112
"max-field-size", "max-rows", "query-timeout",
113
"read-only", "rowset-type", "show-deleted",
114
"table-name", "url", "null", "column", "type",
115
"class", "sync-provider", "sync-provider-name",
116
"sync-provider-vendor", "sync-provider-version",
117
"sync-provider-grade","data-source-lock"};
118
119
/**
120
* A constant representing the tag for the command property.
121
*/
122
private static final int CommandTag = 0;
123
124
/**
125
* A constant representing the tag for the concurrency property.
126
*/
127
private static final int ConcurrencyTag = 1;
128
129
/**
130
* A constant representing the tag for the datasource property.
131
*/
132
private static final int DatasourceTag = 2;
133
134
/**
135
* A constant representing the tag for the escape-processing property.
136
*/
137
private static final int EscapeProcessingTag = 3;
138
139
/**
140
* A constant representing the tag for the fetch-direction property.
141
*/
142
private static final int FetchDirectionTag = 4;
143
144
/**
145
* A constant representing the tag for the fetch-size property.
146
*/
147
private static final int FetchSizeTag = 5;
148
149
/**
150
* A constant representing the tag for the isolation-level property
151
*/
152
private static final int IsolationLevelTag = 6;
153
154
/**
155
* A constant representing the tag for the key-columns property.
156
*/
157
private static final int KeycolsTag = 7;
158
159
/**
160
* A constant representing the tag for the map property.
161
* This map is the type map that specifies the custom mapping
162
* for an SQL user-defined type.
163
*/
164
private static final int MapTag = 8;
165
166
/**
167
* A constant representing the tag for the max-field-size property.
168
*/
169
private static final int MaxFieldSizeTag = 9;
170
171
/**
172
* A constant representing the tag for the max-rows property.
173
*/
174
private static final int MaxRowsTag = 10;
175
176
/**
177
* A constant representing the tag for the query-timeout property.
178
*/
179
private static final int QueryTimeoutTag = 11;
180
181
/**
182
* A constant representing the tag for the read-only property.
183
*/
184
private static final int ReadOnlyTag = 12;
185
186
/**
187
* A constant representing the tag for the rowset-type property.
188
*/
189
private static final int RowsetTypeTag = 13;
190
191
/**
192
* A constant representing the tag for the show-deleted property.
193
*/
194
private static final int ShowDeletedTag = 14;
195
196
/**
197
* A constant representing the tag for the table-name property.
198
*/
199
private static final int TableNameTag = 15;
200
201
/**
202
* A constant representing the tag for the URL property.
203
*/
204
private static final int UrlTag = 16;
205
206
/**
207
* A constant representing the tag for the null property.
208
*/
209
private static final int PropNullTag = 17;
210
211
/**
212
* A constant representing the tag for the column property.
213
*/
214
private static final int PropColumnTag = 18;
215
216
/**
217
* A constant representing the tag for the type property.
218
*/
219
private static final int PropTypeTag = 19;
220
221
/**
222
* A constant representing the tag for the class property.
223
*/
224
private static final int PropClassTag = 20;
225
226
/**
227
* A constant representing the tag for the sync-provider.
228
*/
229
private static final int SyncProviderTag = 21;
230
231
/**
232
* A constant representing the tag for the sync-provider
233
* name
234
*/
235
private static final int SyncProviderNameTag = 22;
236
237
/**
238
* A constant representing the tag for the sync-provider
239
* vendor tag.
240
*/
241
private static final int SyncProviderVendorTag = 23;
242
243
/**
244
* A constant representing the tag for the sync-provider
245
* version tag.
246
*/
247
private static final int SyncProviderVersionTag = 24;
248
249
/**
250
* A constant representing the tag for the sync-provider
251
* grade tag.
252
*/
253
private static final int SyncProviderGradeTag = 25;
254
255
/**
256
* A constant representing the tag for the data source lock.
257
*/
258
private static final int DataSourceLock = 26;
259
260
/**
261
* A listing of the kinds of metadata information available about
262
* the columns in a <code>WebRowSet</code> object.
263
*/
264
private String [] colDef = {"column-count", "column-definition", "column-index",
265
"auto-increment", "case-sensitive", "currency",
266
"nullable", "signed", "searchable",
267
"column-display-size", "column-label", "column-name",
268
"schema-name", "column-precision", "column-scale",
269
"table-name", "catalog-name", "column-type",
270
"column-type-name", "null"};
271
272
273
/**
274
* A constant representing the tag for column-count.
275
*/
276
private static final int ColumnCountTag = 0;
277
278
/**
279
* A constant representing the tag for column-definition.
280
*/
281
private static final int ColumnDefinitionTag = 1;
282
283
/**
284
* A constant representing the tag for column-index.
285
*/
286
private static final int ColumnIndexTag = 2;
287
288
/**
289
* A constant representing the tag for auto-increment.
290
*/
291
private static final int AutoIncrementTag = 3;
292
293
/**
294
* A constant representing the tag for case-sensitive.
295
*/
296
private static final int CaseSensitiveTag = 4;
297
298
/**
299
* A constant representing the tag for currency.
300
*/
301
private static final int CurrencyTag = 5;
302
303
/**
304
* A constant representing the tag for nullable.
305
*/
306
private static final int NullableTag = 6;
307
308
/**
309
* A constant representing the tag for signed.
310
*/
311
private static final int SignedTag = 7;
312
313
/**
314
* A constant representing the tag for searchable.
315
*/
316
private static final int SearchableTag = 8;
317
318
/**
319
* A constant representing the tag for column-display-size.
320
*/
321
private static final int ColumnDisplaySizeTag = 9;
322
323
/**
324
* A constant representing the tag for column-label.
325
*/
326
private static final int ColumnLabelTag = 10;
327
328
/**
329
* A constant representing the tag for column-name.
330
*/
331
private static final int ColumnNameTag = 11;
332
333
/**
334
* A constant representing the tag for schema-name.
335
*/
336
private static final int SchemaNameTag = 12;
337
338
/**
339
* A constant representing the tag for column-precision.
340
*/
341
private static final int ColumnPrecisionTag = 13;
342
343
/**
344
* A constant representing the tag for column-scale.
345
*/
346
private static final int ColumnScaleTag = 14;
347
348
/**
349
* A constant representing the tag for table-name.
350
*/
351
private static final int MetaTableNameTag = 15;
352
353
/**
354
* A constant representing the tag for catalog-name.
355
*/
356
private static final int CatalogNameTag = 16;
357
358
/**
359
* A constant representing the tag for column-type.
360
*/
361
private static final int ColumnTypeTag = 17;
362
363
/**
364
* A constant representing the tag for column-type-name.
365
*/
366
private static final int ColumnTypeNameTag = 18;
367
368
/**
369
* A constant representing the tag for null.
370
*/
371
private static final int MetaNullTag = 19;
372
373
private String [] data = {"currentRow", "columnValue", "insertRow", "deleteRow", "insdel", "updateRow", "null" , "emptyString"};
374
375
private static final int RowTag = 0;
376
private static final int ColTag = 1;
377
private static final int InsTag = 2;
378
private static final int DelTag = 3;
379
private static final int InsDelTag = 4;
380
private static final int UpdTag = 5;
381
private static final int NullTag = 6;
382
private static final int EmptyStringTag = 7;
383
384
/**
385
* A constant indicating the state of this <code>XmlReaderContentHandler</code>
386
* object in which it has not yet been called by the SAX parser and therefore
387
* has no indication of what type of input to expect from the parser next.
388
* <P>
389
* The state is set to <code>INITIAL</code> at the end of each
390
* section, which allows the sections to appear in any order and
391
* still be parsed correctly (except that metadata must be
392
* set before data values can be set).
393
*/
394
private static final int INITIAL = 0;
395
396
/**
397
* A constant indicating the state in which this <code>XmlReaderContentHandler</code>
398
* object expects the next input received from the
399
* SAX parser to be a string corresponding to one of the elements in
400
* <code>properties</code>.
401
*/
402
private static final int PROPERTIES = 1;
403
404
/**
405
* A constant indicating the state in which this <code>XmlReaderContentHandler</code>
406
* object expects the next input received from the
407
* SAX parser to be a string corresponding to one of the elements in
408
* <code>colDef</code>.
409
*/
410
private static final int METADATA = 2;
411
412
/**
413
* A constant indicating the state in which this <code>XmlReaderContentHandler</code>
414
* object expects the next input received from the
415
* SAX parser to be a string corresponding to one of the elements in
416
* <code>data</code>.
417
*/
418
private static final int DATA = 3;
419
420
private JdbcRowSetResourceBundle resBundle;
421
422
/**
423
* Constructs a new <code>XmlReaderContentHandler</code> object that will
424
* assist the SAX parser in reading a <code>WebRowSet</code> object in the
425
* format of an XML document. In addition to setting some default values,
426
* this constructor creates three <code>HashMap</code> objects, one for
427
* properties, one for metadata, and one for data. These hash maps map the
428
* strings sent by the SAX parser to integer constants so that they can be
429
* compared more efficiently in <code>switch</code> statements.
430
*
431
* @param r the <code>RowSet</code> object in XML format that will be read
432
*/
433
public XmlReaderContentHandler(RowSet r) {
434
// keep the rowset we've been given
435
rs = (WebRowSetImpl)r;
436
437
// set-up the token maps
438
initMaps();
439
440
// allocate the collection for the updates
441
updates = new Vector<>();
442
443
// start out with the empty string
444
columnValue = "";
445
propertyValue = "";
446
metaDataValue = "";
447
448
nullVal = false;
449
idx = 0;
450
tempStr = "";
451
tempUpdate = "";
452
tempCommand = "";
453
454
try {
455
resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();
456
} catch(IOException ioe) {
457
throw new RuntimeException(ioe);
458
}
459
}
460
461
/**
462
* Creates and initializes three new <code>HashMap</code> objects that map
463
* the strings returned by the SAX parser to <code>Integer</code>
464
* objects. The strings returned by the parser will match the strings that
465
* are array elements in this <code>XmlReaderContentHandler</code> object's
466
* <code>properties</code>, <code>colDef</code>, or <code>data</code>
467
* fields. For each array element in these fields, there is a corresponding
468
* constant defined. It is to these constants that the strings are mapped.
469
* In the <code>HashMap</code> objects, the string is the key, and the
470
* integer is the value.
471
* <P>
472
* The purpose of the mapping is to make comparisons faster. Because comparing
473
* numbers is more efficient than comparing strings, the strings returned
474
* by the parser are mapped to integers, which can then be used in a
475
* <code>switch</code> statement.
476
*/
477
private void initMaps() {
478
int items, i;
479
480
propMap = new HashMap<>();
481
items = properties.length;
482
483
for (i=0;i<items;i++) {
484
propMap.put(properties[i], Integer.valueOf(i));
485
}
486
487
colDefMap = new HashMap<>();
488
items = colDef.length;
489
490
for (i=0;i<items;i++) {
491
colDefMap.put(colDef[i], Integer.valueOf(i));
492
}
493
494
dataMap = new HashMap<>();
495
items = data.length;
496
497
for (i=0;i<items;i++) {
498
dataMap.put(data[i], Integer.valueOf(i));
499
}
500
501
//Initialize connection map here
502
typeMap = new HashMap<>();
503
}
504
505
public void startDocument() throws SAXException {
506
}
507
508
public void endDocument() throws SAXException {
509
}
510
511
512
/**
513
* Sets this <code>XmlReaderContentHandler</code> object's <code>tag</code>
514
* field if the given name is the key for a tag and this object's state
515
* is not <code>INITIAL</code>. The field is set
516
* to the constant that corresponds to the given element name.
517
* If the state is <code>INITIAL</code>, the state is set to the given
518
* name, which will be one of the sections <code>PROPERTIES</code>,
519
* <code>METADATA</code>, or <code>DATA</code>. In either case, this
520
* method puts this document handler in the proper state for calling
521
* the method <code>endElement</code>.
522
* <P>
523
* If the state is <code>DATA</code> and the tag is <code>RowTag</code>,
524
* <code>DelTag</code>, or <code>InsTag</code>, this method moves the
525
* rowset's cursor to the insert row and sets this
526
* <code>XmlReaderContentHandler</code> object's <code>idx</code>
527
* field to <code>0</code> so that it will be in the proper
528
* state when the parser calls the method <code>endElement</code>.
529
*
530
* @param lName the name of the element; either (1) one of the array
531
* elements in the fields <code>properties</code>,
532
* <code>colDef</code>, or <code>data</code> or
533
* (2) one of the <code>RowSet</code> elements
534
* <code>"properties"</code>, <code>"metadata"</code>, or
535
* <code>"data"</code>
536
* @param attributes <code>org.xml.sax.AttributeList</code> objects that are
537
* attributes of the named section element; may be <code>null</code>
538
* if there are no attributes, which is the case for
539
* <code>WebRowSet</code> objects
540
* @exception SAXException if a general SAX error occurs
541
*/
542
public void startElement(String uri, String lName, String qName, Attributes attributes) throws SAXException {
543
int tag;
544
String name = "";
545
546
name = lName;
547
548
switch (getState()) {
549
case PROPERTIES:
550
551
tempCommand = "";
552
tag = propMap.get(name);
553
if (tag == PropNullTag)
554
setNullValue(true);
555
else
556
setTag(tag);
557
break;
558
case METADATA:
559
tag = colDefMap.get(name);
560
561
if (tag == MetaNullTag)
562
setNullValue(true);
563
else
564
setTag(tag);
565
break;
566
case DATA:
567
568
/**
569
* This has been added to clear out the values of the previous read
570
* so that we should not add up values of data between different tags
571
*/
572
tempStr = "";
573
tempUpdate = "";
574
if(dataMap.get(name) == null) {
575
tag = NullTag;
576
} else if(dataMap.get(name) == EmptyStringTag) {
577
tag = EmptyStringTag;
578
} else {
579
tag = dataMap.get(name);
580
}
581
582
if (tag == NullTag) {
583
setNullValue(true);
584
} else if(tag == EmptyStringTag) {
585
setEmptyStringValue(true);
586
} else {
587
setTag(tag);
588
589
if (tag == RowTag || tag == DelTag || tag == InsTag) {
590
idx = 0;
591
try {
592
rs.moveToInsertRow();
593
} catch (SQLException ex) {
594
;
595
}
596
}
597
}
598
599
break;
600
default:
601
setState(name);
602
}
603
604
}
605
606
/**
607
* Sets the value for the given element if <code>name</code> is one of
608
* the array elements in the fields <code>properties</code>,
609
* <code>colDef</code>, or <code>data</code> and this
610
* <code>XmlReaderContentHandler</code> object's state is not
611
* <code>INITIAL</code>. If the state is <code>INITIAL</code>,
612
* this method does nothing.
613
* <P>
614
* If the state is <code>METADATA</code> and
615
* the argument supplied is <code>"metadata"</code>, the rowset's
616
* metadata is set. If the state is <code>PROPERTIES</code>, the
617
* appropriate property is set using the given name to determine
618
* the appropriate value. If the state is <code>DATA</code> and
619
* the argument supplied is <code>"data"</code>, this method sets
620
* the state to <code>INITIAL</code> and returns. If the argument
621
* supplied is one of the elements in the field <code>data</code>,
622
* this method makes the appropriate changes to the rowset's data.
623
*
624
* @param lName the name of the element; either (1) one of the array
625
* elements in the fields <code>properties</code>,
626
* <code>colDef</code>, or <code>data</code> or
627
* (2) one of the <code>RowSet</code> elements
628
* <code>"properties"</code>, <code>"metadata"</code>, or
629
* <code>"data"</code>
630
*
631
* @exception SAXException if a general SAX error occurs
632
*/
633
@SuppressWarnings("fallthrough")
634
public void endElement(String uri, String lName, String qName) throws SAXException {
635
int tag;
636
637
String name = "";
638
name = lName;
639
640
switch (getState()) {
641
case PROPERTIES:
642
if (name.equals("properties")) {
643
state = INITIAL;
644
break;
645
}
646
647
try {
648
tag = propMap.get(name);
649
switch (tag) {
650
case KeycolsTag:
651
if (keyCols != null) {
652
int i[] = new int[keyCols.size()];
653
for (int j = 0; j < i.length; j++)
654
i[j] = Integer.parseInt(keyCols.elementAt(j));
655
rs.setKeyColumns(i);
656
}
657
break;
658
659
case PropClassTag:
660
//Added the handling for Class tags to take care of maps
661
//Makes an entry into the map upon end of class tag
662
try{
663
typeMap.put(Key_map,sun.reflect.misc.ReflectUtil.forName(Value_map));
664
665
}catch(ClassNotFoundException ex) {
666
throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errmap").toString(), ex.getMessage()));
667
}
668
break;
669
670
case MapTag:
671
//Added the handling for Map to take set the typeMap
672
rs.setTypeMap(typeMap);
673
break;
674
675
default:
676
break;
677
}
678
679
if (getNullValue()) {
680
setPropertyValue(null);
681
setNullValue(false);
682
} else {
683
setPropertyValue(propertyValue);
684
}
685
} catch (SQLException ex) {
686
throw new SAXException(ex.getMessage());
687
}
688
689
// propertyValue need to be reset to an empty string
690
propertyValue = "";
691
setTag(-1);
692
break;
693
case METADATA:
694
if (name.equals("metadata")) {
695
try {
696
rs.setMetaData(md);
697
state = INITIAL;
698
} catch (SQLException ex) {
699
throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errmetadata").toString(), ex.getMessage()));
700
}
701
} else {
702
try {
703
if (getNullValue()) {
704
setMetaDataValue(null);
705
setNullValue(false);
706
} else {
707
setMetaDataValue(metaDataValue);
708
}
709
} catch (SQLException ex) {
710
throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errmetadata").toString(), ex.getMessage()));
711
712
}
713
// metaDataValue needs to be reset to an empty string
714
metaDataValue = "";
715
}
716
setTag(-1);
717
break;
718
case DATA:
719
if (name.equals("data")) {
720
state = INITIAL;
721
return;
722
}
723
724
if(dataMap.get(name) == null) {
725
tag = NullTag;
726
} else {
727
tag = dataMap.get(name);
728
}
729
switch (tag) {
730
case ColTag:
731
try {
732
idx++;
733
if (getNullValue()) {
734
insertValue(null);
735
setNullValue(false);
736
} else {
737
insertValue(tempStr);
738
}
739
// columnValue now need to be reset to the empty string
740
columnValue = "";
741
} catch (SQLException ex) {
742
throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsertval").toString(), ex.getMessage()));
743
}
744
break;
745
case RowTag:
746
try {
747
rs.insertRow();
748
rs.moveToCurrentRow();
749
rs.next();
750
751
// Making this as the original to turn off the
752
// rowInserted flagging
753
rs.setOriginalRow();
754
755
applyUpdates();
756
} catch (SQLException ex) {
757
throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errconstr").toString(), ex.getMessage()));
758
}
759
break;
760
case DelTag:
761
try {
762
rs.insertRow();
763
rs.moveToCurrentRow();
764
rs.next();
765
rs.setOriginalRow();
766
applyUpdates();
767
rs.deleteRow();
768
} catch (SQLException ex) {
769
throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errdel").toString() , ex.getMessage()));
770
}
771
break;
772
case InsTag:
773
try {
774
rs.insertRow();
775
rs.moveToCurrentRow();
776
rs.next();
777
applyUpdates();
778
} catch (SQLException ex) {
779
throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsert").toString() , ex.getMessage()));
780
}
781
break;
782
783
case InsDelTag:
784
try {
785
rs.insertRow();
786
rs.moveToCurrentRow();
787
rs.next();
788
rs.setOriginalRow();
789
applyUpdates();
790
} catch (SQLException ex) {
791
throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsdel").toString() , ex.getMessage()));
792
}
793
break;
794
795
case UpdTag:
796
try {
797
if(getNullValue())
798
{
799
insertValue(null);
800
setNullValue(false);
801
} else if(getEmptyStringValue()) {
802
insertValue("");
803
setEmptyStringValue(false);
804
} else {
805
updates.add(upd);
806
}
807
} catch(SQLException ex) {
808
throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errupdate").toString() , ex.getMessage()));
809
}
810
break;
811
812
default:
813
break;
814
}
815
default:
816
break;
817
}
818
}
819
820
private void applyUpdates() throws SAXException {
821
// now handle any updates
822
if (updates.size() > 0) {
823
try {
824
Object upd[];
825
Iterator<?> i = updates.iterator();
826
while (i.hasNext()) {
827
upd = (Object [])i.next();
828
idx = ((Integer)upd[0]).intValue();
829
830
if(!(lastval.equals(upd[1]))){
831
insertValue((String)(upd[1]));
832
}
833
}
834
835
rs.updateRow();
836
} catch (SQLException ex) {
837
throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errupdrow").toString() , ex.getMessage()));
838
}
839
updates.removeAllElements();
840
}
841
842
843
}
844
845
/**
846
* Sets a property, metadata, or data value with the characters in
847
* the given array of characters, starting with the array element
848
* indicated by <code>start</code> and continuing for <code>length</code>
849
* number of characters.
850
* <P>
851
* The SAX parser invokes this method and supplies
852
* the character array, start position, and length parameter values it
853
* got from parsing the XML document. An application programmer never
854
* invokes this method directly.
855
*
856
* @param ch an array of characters supplied by the SAX parser, all or part of
857
* which will be used to set a value
858
* @param start the position in the given array at which to start
859
* @param length the number of consecutive characters to use
860
*/
861
public void characters(char[] ch, int start, int length) throws SAXException {
862
try {
863
switch (getState()) {
864
case PROPERTIES:
865
propertyValue = new String(ch, start, length);
866
867
/**
868
* This has been added for handling of special characters. When special
869
* characters are encountered the characters function gets called for
870
* each of the characters so we need to append the value got in the
871
* previous call as it is the same data present between the start and
872
* the end tag.
873
**/
874
tempCommand = tempCommand.concat(propertyValue);
875
propertyValue = tempCommand;
876
877
// Added the following check for handling of type tags in maps
878
if(tag == PropTypeTag)
879
{
880
Key_map = propertyValue;
881
}
882
883
// Added the following check for handling of class tags in maps
884
else if(tag == PropClassTag)
885
{
886
Value_map = propertyValue;
887
}
888
break;
889
890
case METADATA:
891
892
// The parser will come here after the endElement as there is
893
// "\n" in the after endTag is printed. This will cause a problem
894
// when the data between the tags is an empty string so adding
895
// below condition to take care of that situation.
896
897
if (tag == -1)
898
{
899
break;
900
}
901
902
metaDataValue = new String(ch, start, length);
903
break;
904
case DATA:
905
setDataValue(ch, start, length);
906
break;
907
default:
908
;
909
}
910
} catch (SQLException ex) {
911
throw new SAXException(resBundle.handleGetObject("xmlrch.chars").toString() + ex.getMessage());
912
}
913
}
914
915
private void setState(String s) throws SAXException {
916
if (s.equals("webRowSet")) {
917
state = INITIAL;
918
} else if (s.equals("properties")) {
919
if (state != PROPERTIES)
920
state = PROPERTIES;
921
else
922
state = INITIAL;
923
} else if (s.equals("metadata")) {
924
if (state != METADATA)
925
state = METADATA;
926
else
927
state = INITIAL;
928
} else if (s.equals("data")) {
929
if (state != DATA)
930
state = DATA;
931
else
932
state = INITIAL;
933
}
934
935
}
936
937
/**
938
* Retrieves the current state of this <code>XmlReaderContentHandler</code>
939
* object's rowset, which is stored in the document handler's
940
* <code>state</code> field.
941
*
942
* @return one of the following constants:
943
* <code>XmlReaderContentHandler.PROPERTIES</code>
944
* <code>XmlReaderContentHandler.METADATA</code>
945
* <code>XmlReaderContentHandler.DATA</code>
946
* <code>XmlReaderContentHandler.INITIAL</code>
947
*/
948
private int getState() {
949
return state;
950
}
951
952
private void setTag(int t) {
953
tag = t;
954
}
955
956
private int getTag() {
957
return tag;
958
}
959
960
private void setNullValue(boolean n) {
961
nullVal = n;
962
}
963
964
private boolean getNullValue() {
965
return nullVal;
966
}
967
968
private void setEmptyStringValue(boolean e) {
969
emptyStringVal = e;
970
}
971
972
private boolean getEmptyStringValue() {
973
return emptyStringVal;
974
}
975
976
private String getStringValue(String s) {
977
return s;
978
}
979
980
private int getIntegerValue(String s) {
981
return Integer.parseInt(s);
982
}
983
984
private boolean getBooleanValue(String s) {
985
986
return Boolean.valueOf(s).booleanValue();
987
}
988
989
private java.math.BigDecimal getBigDecimalValue(String s) {
990
return new java.math.BigDecimal(s);
991
}
992
993
private byte getByteValue(String s) {
994
return Byte.parseByte(s);
995
}
996
997
private short getShortValue(String s) {
998
return Short.parseShort(s);
999
}
1000
1001
private long getLongValue(String s) {
1002
return Long.parseLong(s);
1003
}
1004
1005
private float getFloatValue(String s) {
1006
return Float.parseFloat(s);
1007
}
1008
1009
private double getDoubleValue(String s) {
1010
return Double.parseDouble(s);
1011
}
1012
1013
private byte[] getBinaryValue(String s) {
1014
return s.getBytes();
1015
}
1016
1017
private java.sql.Date getDateValue(String s) {
1018
return new java.sql.Date(getLongValue(s));
1019
}
1020
1021
private java.sql.Time getTimeValue(String s) {
1022
return new java.sql.Time(getLongValue(s));
1023
}
1024
1025
private java.sql.Timestamp getTimestampValue(String s) {
1026
return new java.sql.Timestamp(getLongValue(s));
1027
}
1028
1029
private void setPropertyValue(String s) throws SQLException {
1030
// find out if we are going to be dealing with a null
1031
boolean nullValue = getNullValue();
1032
1033
switch(getTag()) {
1034
case CommandTag:
1035
if (nullValue)
1036
; //rs.setCommand(null);
1037
else
1038
rs.setCommand(s);
1039
break;
1040
case ConcurrencyTag:
1041
if (nullValue)
1042
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1043
else
1044
rs.setConcurrency(getIntegerValue(s));
1045
break;
1046
case DatasourceTag:
1047
if (nullValue)
1048
rs.setDataSourceName(null);
1049
else
1050
rs.setDataSourceName(s);
1051
break;
1052
case EscapeProcessingTag:
1053
if (nullValue)
1054
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1055
else
1056
rs.setEscapeProcessing(getBooleanValue(s));
1057
break;
1058
case FetchDirectionTag:
1059
if (nullValue)
1060
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1061
else
1062
rs.setFetchDirection(getIntegerValue(s));
1063
break;
1064
case FetchSizeTag:
1065
if (nullValue)
1066
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1067
else
1068
rs.setFetchSize(getIntegerValue(s));
1069
break;
1070
case IsolationLevelTag:
1071
if (nullValue)
1072
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1073
else
1074
rs.setTransactionIsolation(getIntegerValue(s));
1075
break;
1076
case KeycolsTag:
1077
break;
1078
case PropColumnTag:
1079
if (keyCols == null)
1080
keyCols = new Vector<>();
1081
keyCols.add(s);
1082
break;
1083
case MapTag:
1084
break;
1085
case MaxFieldSizeTag:
1086
if (nullValue)
1087
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1088
else
1089
rs.setMaxFieldSize(getIntegerValue(s));
1090
break;
1091
case MaxRowsTag:
1092
if (nullValue)
1093
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1094
else
1095
rs.setMaxRows(getIntegerValue(s));
1096
break;
1097
case QueryTimeoutTag:
1098
if (nullValue)
1099
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1100
else
1101
rs.setQueryTimeout(getIntegerValue(s));
1102
break;
1103
case ReadOnlyTag:
1104
if (nullValue)
1105
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1106
else
1107
rs.setReadOnly(getBooleanValue(s));
1108
break;
1109
case RowsetTypeTag:
1110
if (nullValue) {
1111
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1112
} else {
1113
//rs.setType(getIntegerValue(s));
1114
String strType = getStringValue(s);
1115
int iType = 0;
1116
1117
if(strType.trim().equals("ResultSet.TYPE_SCROLL_INSENSITIVE")) {
1118
iType = 1004;
1119
} else if(strType.trim().equals("ResultSet.TYPE_SCROLL_SENSITIVE")) {
1120
iType = 1005;
1121
} else if(strType.trim().equals("ResultSet.TYPE_FORWARD_ONLY")) {
1122
iType = 1003;
1123
}
1124
rs.setType(iType);
1125
}
1126
break;
1127
case ShowDeletedTag:
1128
if (nullValue)
1129
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1130
else
1131
rs.setShowDeleted(getBooleanValue(s));
1132
break;
1133
case TableNameTag:
1134
if (nullValue)
1135
//rs.setTableName(null);
1136
;
1137
else
1138
rs.setTableName(s);
1139
break;
1140
case UrlTag:
1141
if (nullValue)
1142
rs.setUrl(null);
1143
else
1144
rs.setUrl(s);
1145
break;
1146
case SyncProviderNameTag:
1147
if (nullValue) {
1148
rs.setSyncProvider(null);
1149
} else {
1150
String str = s.substring(0,s.indexOf('@')+1);
1151
rs.setSyncProvider(str);
1152
}
1153
break;
1154
case SyncProviderVendorTag:
1155
// to be implemented
1156
break;
1157
case SyncProviderVersionTag:
1158
// to be implemented
1159
break;
1160
case SyncProviderGradeTag:
1161
// to be implemented
1162
break;
1163
case DataSourceLock:
1164
// to be implemented
1165
break;
1166
default:
1167
break;
1168
}
1169
1170
}
1171
1172
private void setMetaDataValue(String s) throws SQLException {
1173
// find out if we are going to be dealing with a null
1174
boolean nullValue = getNullValue();
1175
1176
switch (getTag()) {
1177
case ColumnCountTag:
1178
md = new RowSetMetaDataImpl();
1179
idx = 0;
1180
1181
if (nullValue) {
1182
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1183
} else {
1184
md.setColumnCount(getIntegerValue(s));
1185
}
1186
break;
1187
case ColumnDefinitionTag:
1188
break;
1189
case ColumnIndexTag:
1190
idx++;
1191
break;
1192
case AutoIncrementTag:
1193
if (nullValue)
1194
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1195
else
1196
md.setAutoIncrement(idx, getBooleanValue(s));
1197
break;
1198
case CaseSensitiveTag:
1199
if (nullValue)
1200
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1201
else
1202
md.setCaseSensitive(idx, getBooleanValue(s));
1203
break;
1204
case CurrencyTag:
1205
if (nullValue)
1206
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1207
else
1208
md.setCurrency(idx, getBooleanValue(s));
1209
break;
1210
case NullableTag:
1211
if (nullValue)
1212
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1213
else
1214
md.setNullable(idx, getIntegerValue(s));
1215
break;
1216
case SignedTag:
1217
if (nullValue)
1218
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1219
else
1220
md.setSigned(idx, getBooleanValue(s));
1221
break;
1222
case SearchableTag:
1223
if (nullValue)
1224
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1225
else
1226
md.setSearchable(idx, getBooleanValue(s));
1227
break;
1228
case ColumnDisplaySizeTag:
1229
if (nullValue)
1230
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1231
else
1232
md.setColumnDisplaySize(idx, getIntegerValue(s));
1233
break;
1234
case ColumnLabelTag:
1235
if (nullValue)
1236
md.setColumnLabel(idx, null);
1237
else
1238
md.setColumnLabel(idx, s);
1239
break;
1240
case ColumnNameTag:
1241
if (nullValue)
1242
md.setColumnName(idx, null);
1243
else
1244
md.setColumnName(idx, s);
1245
1246
break;
1247
case SchemaNameTag:
1248
if (nullValue) {
1249
md.setSchemaName(idx, null); }
1250
else
1251
md.setSchemaName(idx, s);
1252
break;
1253
case ColumnPrecisionTag:
1254
if (nullValue)
1255
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1256
else
1257
md.setPrecision(idx, getIntegerValue(s));
1258
break;
1259
case ColumnScaleTag:
1260
if (nullValue)
1261
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1262
else
1263
md.setScale(idx, getIntegerValue(s));
1264
break;
1265
case MetaTableNameTag:
1266
if (nullValue)
1267
md.setTableName(idx, null);
1268
else
1269
md.setTableName(idx, s);
1270
break;
1271
case CatalogNameTag:
1272
if (nullValue)
1273
md.setCatalogName(idx, null);
1274
else
1275
md.setCatalogName(idx, s);
1276
break;
1277
case ColumnTypeTag:
1278
if (nullValue)
1279
throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1280
else
1281
md.setColumnType(idx, getIntegerValue(s));
1282
break;
1283
case ColumnTypeNameTag:
1284
if (nullValue)
1285
md.setColumnTypeName(idx, null);
1286
else
1287
md.setColumnTypeName(idx, s);
1288
break;
1289
default:
1290
//System.out.println("MetaData: Unknown Tag: (" + getTag() + ")");
1291
break;
1292
1293
}
1294
}
1295
1296
private void setDataValue(char[] ch, int start, int len) throws SQLException {
1297
switch (getTag()) {
1298
case ColTag:
1299
columnValue = new String(ch, start, len);
1300
/**
1301
* This has been added for handling of special characters. When special
1302
* characters are encountered the characters function gets called for
1303
* each of the characters so we need to append the value got in the
1304
* previous call as it is the same data present between the start and
1305
* the end tag.
1306
**/
1307
tempStr = tempStr.concat(columnValue);
1308
break;
1309
case UpdTag:
1310
upd = new Object[2];
1311
1312
/**
1313
* This has been added for handling of special characters. When special
1314
* characters are encountered the characters function gets called for
1315
* each of the characters so we need to append the value got in the
1316
* previous call as it is the same data present between the start and
1317
* the end tag.
1318
**/
1319
1320
tempUpdate = tempUpdate.concat(new String(ch,start,len));
1321
upd[0] = Integer.valueOf(idx);
1322
upd[1] = tempUpdate;
1323
//updates.add(upd);
1324
1325
lastval = (String)upd[1];
1326
//insertValue(ch, start, len);
1327
break;
1328
case InsTag:
1329
1330
}
1331
}
1332
1333
private void insertValue(String s) throws SQLException {
1334
1335
if (getNullValue()) {
1336
rs.updateNull(idx);
1337
return;
1338
}
1339
1340
// no longer have to deal with those pesky nulls.
1341
int type = rs.getMetaData().getColumnType(idx);
1342
switch (type) {
1343
case java.sql.Types.BIT:
1344
rs.updateBoolean(idx, getBooleanValue(s));
1345
break;
1346
case java.sql.Types.BOOLEAN:
1347
rs.updateBoolean(idx, getBooleanValue(s));
1348
break;
1349
case java.sql.Types.SMALLINT:
1350
case java.sql.Types.TINYINT:
1351
rs.updateShort(idx, getShortValue(s));
1352
break;
1353
case java.sql.Types.INTEGER:
1354
rs.updateInt(idx, getIntegerValue(s));
1355
break;
1356
case java.sql.Types.BIGINT:
1357
rs.updateLong(idx, getLongValue(s));
1358
break;
1359
case java.sql.Types.REAL:
1360
case java.sql.Types.FLOAT:
1361
rs.updateFloat(idx, getFloatValue(s));
1362
break;
1363
case java.sql.Types.DOUBLE:
1364
rs.updateDouble(idx, getDoubleValue(s));
1365
break;
1366
case java.sql.Types.NUMERIC:
1367
case java.sql.Types.DECIMAL:
1368
rs.updateObject(idx, getBigDecimalValue(s));
1369
break;
1370
case java.sql.Types.BINARY:
1371
case java.sql.Types.VARBINARY:
1372
case java.sql.Types.LONGVARBINARY:
1373
rs.updateBytes(idx, getBinaryValue(s));
1374
break;
1375
case java.sql.Types.DATE:
1376
rs.updateDate(idx, getDateValue(s));
1377
break;
1378
case java.sql.Types.TIME:
1379
rs.updateTime(idx, getTimeValue(s));
1380
break;
1381
case java.sql.Types.TIMESTAMP:
1382
rs.updateTimestamp(idx, getTimestampValue(s));
1383
break;
1384
case java.sql.Types.CHAR:
1385
case java.sql.Types.VARCHAR:
1386
case java.sql.Types.LONGVARCHAR:
1387
rs.updateString(idx, getStringValue(s));
1388
break;
1389
default:
1390
1391
}
1392
1393
}
1394
1395
/**
1396
* Throws the given <code>SAXParseException</code> object. This
1397
* exception was originally thrown by the SAX parser and is passed
1398
* to the method <code>error</code> when the SAX parser invokes it.
1399
*
1400
* @param e the <code>SAXParseException</code> object to throw
1401
*/
1402
public void error (SAXParseException e) throws SAXParseException {
1403
throw e;
1404
}
1405
1406
// dump warnings too
1407
/**
1408
* Prints a warning message to <code>System.out</code> giving the line
1409
* number and uri for what caused the warning plus a message explaining
1410
* the reason for the warning. This method is invoked by the SAX parser.
1411
*
1412
* @param err a warning generated by the SAX parser
1413
*/
1414
public void warning (SAXParseException err) throws SAXParseException {
1415
System.out.println (MessageFormat.format(resBundle.handleGetObject("xmlrch.warning").toString(), new Object[] { err.getMessage(), err.getLineNumber(), err.getSystemId() }));
1416
}
1417
1418
/**
1419
*
1420
*/
1421
public void notationDecl(String name, String publicId, String systemId) {
1422
1423
}
1424
1425
/**
1426
*
1427
*/
1428
public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName) {
1429
1430
}
1431
1432
/**
1433
* Returns the current row of this <code>Rowset</code>object.
1434
* The ResultSet's cursor is positioned at the Row which is needed
1435
*
1436
* @return the <code>Row</code> object on which the <code>RowSet</code>
1437
* implementation objects's cursor is positioned
1438
*/
1439
private Row getPresentRow(WebRowSetImpl rs) throws SQLException {
1440
//rs.setOriginalRow();
1441
// ResultSetMetaData rsmd = rs.getMetaData();
1442
// int numCols = rsmd.getColumnCount();
1443
// Object vals[] = new Object[numCols];
1444
// for(int j = 1; j<= numCols ; j++){
1445
// vals[j-1] = rs.getObject(j);
1446
// }
1447
// return(new Row(numCols, vals));
1448
return null;
1449
}
1450
1451
1452
1453
1454
}
1455
1456