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/XmlReaderContentHandler.java (1 of 18352 files). Show all

Unified · Split

java/pkg/com/sun/rowset/internal/XmlReaderContentHandler.java+1452−0
@@ -0,0 +1,1452 @@
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 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 propMap;
75+ private HashMap colDefMap;
76+ private HashMap dataMap;
77+
78+ private HashMap typeMap;
79+
80+ private Vector updates;
81+ private Vector 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 final static int CommandTag = 0;
123+
124+ /**
125+ * A constant representing the tag for the concurrency property.
126+ */
127+ private final static int ConcurrencyTag = 1;
128+
129+ /**
130+ * A constant representing the tag for the datasource property.
131+ */
132+ private final static int DatasourceTag = 2;
133+
134+ /**
135+ * A constant representing the tag for the escape-processing property.
136+ */
137+ private final static int EscapeProcessingTag = 3;
138+
139+ /**
140+ * A constant representing the tag for the fetch-direction property.
141+ */
142+ private final static int FetchDirectionTag = 4;
143+
144+ /**
145+ * A constant representing the tag for the fetch-size property.
146+ */
147+ private final static int FetchSizeTag = 5;
148+
149+ /**
150+ * A constant representing the tag for the isolation-level property
151+ */
152+ private final static int IsolationLevelTag = 6;
153+
154+ /**
155+ * A constant representing the tag for the key-columns property.
156+ */
157+ private final static 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 final static int MapTag = 8;
165+
166+ /**
167+ * A constant representing the tag for the max-field-size property.
168+ */
169+ private final static int MaxFieldSizeTag = 9;
170+
171+ /**
172+ * A constant representing the tag for the max-rows property.
173+ */
174+ private final static int MaxRowsTag = 10;
175+
176+ /**
177+ * A constant representing the tag for the query-timeout property.
178+ */
179+ private final static int QueryTimeoutTag = 11;
180+
181+ /**
182+ * A constant representing the tag for the read-only property.
183+ */
184+ private final static int ReadOnlyTag = 12;
185+
186+ /**
187+ * A constant representing the tag for the rowset-type property.
188+ */
189+ private final static int RowsetTypeTag = 13;
190+
191+ /**
192+ * A constant representing the tag for the show-deleted property.
193+ */
194+ private final static int ShowDeletedTag = 14;
195+
196+ /**
197+ * A constant representing the tag for the table-name property.
198+ */
199+ private final static int TableNameTag = 15;
200+
201+ /**
202+ * A constant representing the tag for the URL property.
203+ */
204+ private final static int UrlTag = 16;
205+
206+ /**
207+ * A constant representing the tag for the null property.
208+ */
209+ private final static int PropNullTag = 17;
210+
211+ /**
212+ * A constant representing the tag for the column property.
213+ */
214+ private final static int PropColumnTag = 18;
215+
216+ /**
217+ * A constant representing the tag for the type property.
218+ */
219+ private final static int PropTypeTag = 19;
220+
221+ /**
222+ * A constant representing the tag for the class property.
223+ */
224+ private final static int PropClassTag = 20;
225+
226+ /**
227+ * A constant representing the tag for the sync-provider.
228+ */
229+ private final static int SyncProviderTag = 21;
230+
231+ /**
232+ * A constant representing the tag for the sync-provider
233+ * name
234+ */
235+ private final static int SyncProviderNameTag = 22;
236+
237+ /**
238+ * A constant representing the tag for the sync-provider
239+ * vendor tag.
240+ */
241+ private final static int SyncProviderVendorTag = 23;
242+
243+ /**
244+ * A constant representing the tag for the sync-provider
245+ * version tag.
246+ */
247+ private final static int SyncProviderVersionTag = 24;
248+
249+ /**
250+ * A constant representing the tag for the sync-provider
251+ * grade tag.
252+ */
253+ private final static int SyncProviderGradeTag = 25;
254+
255+ /**
256+ * A constant representing the tag for the data source lock.
257+ */
258+ private final static 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 final static int ColumnCountTag = 0;
277+
278+ /**
279+ * A constant representing the tag for column-definition.
280+ */
281+ private final static int ColumnDefinitionTag = 1;
282+
283+ /**
284+ * A constant representing the tag for column-index.
285+ */
286+ private final static int ColumnIndexTag = 2;
287+
288+ /**
289+ * A constant representing the tag for auto-increment.
290+ */
291+ private final static int AutoIncrementTag = 3;
292+
293+ /**
294+ * A constant representing the tag for case-sensitive.
295+ */
296+ private final static int CaseSensitiveTag = 4;
297+
298+ /**
299+ * A constant representing the tag for currency.
300+ */
301+ private final static int CurrencyTag = 5;
302+
303+ /**
304+ * A constant representing the tag for nullable.
305+ */
306+ private final static int NullableTag = 6;
307+
308+ /**
309+ * A constant representing the tag for signed.
310+ */
311+ private final static int SignedTag = 7;
312+
313+ /**
314+ * A constant representing the tag for searchable.
315+ */
316+ private final static int SearchableTag = 8;
317+
318+ /**
319+ * A constant representing the tag for column-display-size.
320+ */
321+ private final static int ColumnDisplaySizeTag = 9;
322+
323+ /**
324+ * A constant representing the tag for column-label.
325+ */
326+ private final static int ColumnLabelTag = 10;
327+
328+ /**
329+ * A constant representing the tag for column-name.
330+ */
331+ private final static int ColumnNameTag = 11;
332+
333+ /**
334+ * A constant representing the tag for schema-name.
335+ */
336+ private final static int SchemaNameTag = 12;
337+
338+ /**
339+ * A constant representing the tag for column-precision.
340+ */
341+ private final static int ColumnPrecisionTag = 13;
342+
343+ /**
344+ * A constant representing the tag for column-scale.
345+ */
346+ private final static int ColumnScaleTag = 14;
347+
348+ /**
349+ * A constant representing the tag for table-name.
350+ */
351+ private final static int MetaTableNameTag = 15;
352+
353+ /**
354+ * A constant representing the tag for catalog-name.
355+ */
356+ private final static int CatalogNameTag = 16;
357+
358+ /**
359+ * A constant representing the tag for column-type.
360+ */
361+ private final static int ColumnTypeTag = 17;
362+
363+ /**
364+ * A constant representing the tag for column-type-name.
365+ */
366+ private final static int ColumnTypeNameTag = 18;
367+
368+ /**
369+ * A constant representing the tag for null.
370+ */
371+ private final static int MetaNullTag = 19;
372+
373+ private String [] data = {"currentRow", "columnValue", "insertRow", "deleteRow", "insdel", "updateRow", "null" , "emptyString"};
374+
375+ private final static int RowTag = 0;
376+ private final static int ColTag = 1;
377+ private final static int InsTag = 2;
378+ private final static int DelTag = 3;
379+ private final static int InsDelTag = 4;
380+ private final static int UpdTag = 5;
381+ private final static int NullTag = 6;
382+ private final static 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 final static 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 final static 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 final static 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 final static 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 = ((Integer)propMap.get(name)).intValue();
553+ if (tag == PropNullTag)
554+ setNullValue(true);
555+ else
556+ setTag(tag);
557+ break;
558+ case METADATA:
559+ tag = ((Integer)colDefMap.get(name)).intValue();
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(((Integer)dataMap.get(name)).intValue() == EmptyStringTag) {
577+ tag = EmptyStringTag;
578+ } else {
579+ tag = ((Integer)dataMap.get(name)).intValue();
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+ public void endElement(String uri, String lName, String qName) throws SAXException {
634+ int tag;
635+
636+ String name = "";
637+ name = lName;
638+
639+ switch (getState()) {
640+ case PROPERTIES:
641+ if (name.equals("properties")) {
642+ state = INITIAL;
643+ break;
644+ }
645+
646+ try {
647+ tag = ((Integer)propMap.get(name)).intValue();
648+ switch (tag) {
649+ case KeycolsTag:
650+ if (keyCols != null) {
651+ int i[] = new int[keyCols.size()];
652+ for (int j = 0; j < i.length; j++)
653+ i[j] = Integer.parseInt((String)keyCols.elementAt(j));
654+ rs.setKeyColumns(i);
655+ }
656+ break;
657+
658+ case PropClassTag:
659+ //Added the handling for Class tags to take care of maps
660+ //Makes an entry into the map upon end of class tag
661+ try{
662+ typeMap.put(Key_map,Class.forName(Value_map));
663+
664+ }catch(ClassNotFoundException ex) {
665+ throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errmap").toString(), ex.getMessage()));
666+ }
667+ break;
668+
669+ case MapTag:
670+ //Added the handling for Map to take set the typeMap
671+ rs.setTypeMap(typeMap);
672+ break;
673+
674+ default:
675+ break;
676+ }
677+
678+ if (getNullValue()) {
679+ setPropertyValue(null);
680+ setNullValue(false);
681+ } else {
682+ setPropertyValue(propertyValue);
683+ }
684+ } catch (SQLException ex) {
685+ throw new SAXException(ex.getMessage());
686+ }
687+
688+ // propertyValue need to be reset to an empty string
689+ propertyValue = "";
690+ setTag(-1);
691+ break;
692+ case METADATA:
693+ if (name.equals("metadata")) {
694+ try {
695+ rs.setMetaData(md);
696+ state = INITIAL;
697+ } catch (SQLException ex) {
698+ throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errmetadata").toString(), ex.getMessage()));
699+ }
700+ } else {
701+ try {
702+ if (getNullValue()) {
703+ setMetaDataValue(null);
704+ setNullValue(false);
705+ } else {
706+ setMetaDataValue(metaDataValue);
707+ }
708+ } catch (SQLException ex) {
709+ throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errmetadata").toString(), ex.getMessage()));
710+
711+ }
712+ // metaDataValue needs to be reset to an empty string
713+ metaDataValue = "";
714+ }
715+ setTag(-1);
716+ break;
717+ case DATA:
718+ if (name.equals("data")) {
719+ state = INITIAL;
720+ return;
721+ }
722+
723+ if(dataMap.get(name) == null) {
724+ tag = NullTag;
725+ } else {
726+ tag = ((Integer)dataMap.get(name)).intValue();
727+ }
728+ switch (tag) {
729+ case ColTag:
730+ try {
731+ idx++;
732+ if (getNullValue()) {
733+ insertValue(null);
734+ setNullValue(false);
735+ } else {
736+ insertValue(tempStr);
737+ }
738+ // columnValue now need to be reset to the empty string
739+ columnValue = "";
740+ } catch (SQLException ex) {
741+ throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsertval").toString(), ex.getMessage()));
742+ }
743+ break;
744+ case RowTag:
745+ try {
746+ rs.insertRow();
747+ rs.moveToCurrentRow();
748+ rs.next();
749+
750+ // Making this as the original to turn off the
751+ // rowInserted flagging
752+ rs.setOriginalRow();
753+
754+ applyUpdates();
755+ } catch (SQLException ex) {
756+ throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errconstr").toString(), ex.getMessage()));
757+ }
758+ break;
759+ case DelTag:
760+ try {
761+ rs.insertRow();
762+ rs.moveToCurrentRow();
763+ rs.next();
764+ rs.setOriginalRow();
765+ applyUpdates();
766+ } catch (SQLException ex) {
767+ throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errdel").toString() , ex.getMessage()));
768+ }
769+ break;
770+ case InsTag:
771+ try {
772+ rs.insertRow();
773+ rs.moveToCurrentRow();
774+ rs.next();
775+ applyUpdates();
776+ } catch (SQLException ex) {
777+ throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsert").toString() , ex.getMessage()));
778+ }
779+ break;
780+
781+ case InsDelTag:
782+ try {
783+ rs.insertRow();
784+ rs.moveToCurrentRow();
785+ rs.next();
786+ rs.setOriginalRow();
787+ applyUpdates();
788+ } catch (SQLException ex) {
789+ throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsdel").toString() , ex.getMessage()));
790+ }
791+ break;
792+
793+ case UpdTag:
794+ try {
795+ if(getNullValue())
796+ {
797+ insertValue(null);
798+ setNullValue(false);
799+ } else if(getEmptyStringValue()) {
800+ insertValue("");
801+ setEmptyStringValue(false);
802+ } else {
803+ updates.add(upd);
804+ }
805+ } catch(SQLException ex) {
806+ throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errupdate").toString() , ex.getMessage()));
807+ }
808+ break;
809+
810+ default:
811+ break;
812+ }
813+ default:
814+ break;
815+ }
816+ }
817+
818+ private void applyUpdates() throws SAXException {
819+ // now handle any updates
820+ if (updates.size() > 0) {
821+ try {
822+ Object upd[];
823+ Iterator i = updates.iterator();
824+ while (i.hasNext()) {
825+ upd = (Object [])i.next();
826+ idx = ((Integer)upd[0]).intValue();
827+
828+ if(!(lastval.equals(upd[1]))){
829+ insertValue((String)(upd[1]));
830+ }
831+ }
832+
833+ rs.updateRow();
834+ } catch (SQLException ex) {
835+ throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errupdrow").toString() , ex.getMessage()));
836+ }
837+ updates.removeAllElements();
838+ }
839+
840+
841+ }
842+
843+ /**
844+ * Sets a property, metadata, or data value with the characters in
845+ * the given array of characters, starting with the array element
846+ * indicated by <code>start</code> and continuing for <code>length</code>
847+ * number of characters.
848+ * <P>
849+ * The SAX parser invokes this method and supplies
850+ * the character array, start position, and length parameter values it
851+ * got from parsing the XML document. An application programmer never
852+ * invokes this method directly.
853+ *
854+ * @param ch an array of characters supplied by the SAX parser, all or part of
855+ * which will be used to set a value
856+ * @param start the position in the given array at which to start
857+ * @param length the number of consecutive characters to use
858+ */
859+ public void characters(char[] ch, int start, int length) throws SAXException {
860+ try {
861+ switch (getState()) {
862+ case PROPERTIES:
863+ propertyValue = new String(ch, start, length);
864+
865+ /**
866+ * This has been added for handling of special characters. When special
867+ * characters are encountered the characters function gets called for
868+ * each of the characters so we need to append the value got in the
869+ * previous call as it is the same data present between the start and
870+ * the end tag.
871+ **/
872+ tempCommand = tempCommand.concat(propertyValue);
873+ propertyValue = tempCommand;
874+
875+ // Added the following check for handling of type tags in maps
876+ if(tag == PropTypeTag)
877+ {
878+ Key_map = propertyValue;
879+ }
880+
881+ // Added the following check for handling of class tags in maps
882+ else if(tag == PropClassTag)
883+ {
884+ Value_map = propertyValue;
885+ }
886+ break;
887+
888+ case METADATA:
889+
890+ // The parser will come here after the endElement as there is
891+ // "\n" in the after endTag is printed. This will cause a problem
892+ // when the data between the tags is an empty string so adding
893+ // below condition to take care of that situation.
894+
895+ if (tag == -1)
896+ {
897+ break;
898+ }
899+
900+ metaDataValue = new String(ch, start, length);
901+ break;
902+ case DATA:
903+ setDataValue(ch, start, length);
904+ break;
905+ default:
906+ ;
907+ }
908+ } catch (SQLException ex) {
909+ throw new SAXException(resBundle.handleGetObject("xmlrch.chars").toString() + ex.getMessage());
910+ }
911+ }
912+
913+ private void setState(String s) throws SAXException {
914+ if (s.equals("webRowSet")) {
915+ state = INITIAL;
916+ } else if (s.equals("properties")) {
917+ if (state != PROPERTIES)
918+ state = PROPERTIES;
919+ else
920+ state = INITIAL;
921+ } else if (s.equals("metadata")) {
922+ if (state != METADATA)
923+ state = METADATA;
924+ else
925+ state = INITIAL;
926+ } else if (s.equals("data")) {
927+ if (state != DATA)
928+ state = DATA;
929+ else
930+ state = INITIAL;
931+ }
932+
933+ }
934+
935+ /**
936+ * Retrieves the current state of this <code>XmlReaderContentHandler</code>
937+ * object's rowset, which is stored in the document handler's
938+ * <code>state</code> field.
939+ *
940+ * @return one of the following constants:
941+ * <code>XmlReaderContentHandler.PROPERTIES</code>
942+ * <code>XmlReaderContentHandler.METADATA</code>
943+ * <code>XmlReaderContentHandler.DATA</code>
944+ * <code>XmlReaderContentHandler.INITIAL</code>
945+ */
946+ private int getState() {
947+ return state;
948+ }
949+
950+ private void setTag(int t) {
951+ tag = t;
952+ }
953+
954+ private int getTag() {
955+ return tag;
956+ }
957+
958+ private void setNullValue(boolean n) {
959+ nullVal = n;
960+ }
961+
962+ private boolean getNullValue() {
963+ return nullVal;
964+ }
965+
966+ private void setEmptyStringValue(boolean e) {
967+ emptyStringVal = e;
968+ }
969+
970+ private boolean getEmptyStringValue() {
971+ return emptyStringVal;
972+ }
973+
974+ private String getStringValue(String s) {
975+ return s;
976+ }
977+
978+ private int getIntegerValue(String s) {
979+ return Integer.parseInt(s);
980+ }
981+
982+ private boolean getBooleanValue(String s) {
983+
984+ return Boolean.valueOf(s).booleanValue();
985+ }
986+
987+ private java.math.BigDecimal getBigDecimalValue(String s) {
988+ return new java.math.BigDecimal(s);
989+ }
990+
991+ private byte getByteValue(String s) {
992+ return Byte.parseByte(s);
993+ }
994+
995+ private short getShortValue(String s) {
996+ return Short.parseShort(s);
997+ }
998+
999+ private long getLongValue(String s) {
1000+ return Long.parseLong(s);
1001+ }
1002+
1003+ private float getFloatValue(String s) {
1004+ return Float.parseFloat(s);
1005+ }
1006+
1007+ private double getDoubleValue(String s) {
1008+ return Double.parseDouble(s);
1009+ }
1010+
1011+ private byte[] getBinaryValue(String s) {
1012+ return s.getBytes();
1013+ }
1014+
1015+ private java.sql.Date getDateValue(String s) {
1016+ return new java.sql.Date(getLongValue(s));
1017+ }
1018+
1019+ private java.sql.Time getTimeValue(String s) {
1020+ return new java.sql.Time(getLongValue(s));
1021+ }
1022+
1023+ private java.sql.Timestamp getTimestampValue(String s) {
1024+ return new java.sql.Timestamp(getLongValue(s));
1025+ }
1026+
1027+ private void setPropertyValue(String s) throws SQLException {
1028+ // find out if we are going to be dealing with a null
1029+ boolean nullValue = getNullValue();
1030+
1031+ switch(getTag()) {
1032+ case CommandTag:
1033+ if (nullValue)
1034+ ; //rs.setCommand(null);
1035+ else
1036+ rs.setCommand(s);
1037+ break;
1038+ case ConcurrencyTag:
1039+ if (nullValue)
1040+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1041+ else
1042+ rs.setConcurrency(getIntegerValue(s));
1043+ break;
1044+ case DatasourceTag:
1045+ if (nullValue)
1046+ rs.setDataSourceName(null);
1047+ else
1048+ rs.setDataSourceName(s);
1049+ break;
1050+ case EscapeProcessingTag:
1051+ if (nullValue)
1052+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1053+ else
1054+ rs.setEscapeProcessing(getBooleanValue(s));
1055+ break;
1056+ case FetchDirectionTag:
1057+ if (nullValue)
1058+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1059+ else
1060+ rs.setFetchDirection(getIntegerValue(s));
1061+ break;
1062+ case FetchSizeTag:
1063+ if (nullValue)
1064+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1065+ else
1066+ rs.setFetchSize(getIntegerValue(s));
1067+ break;
1068+ case IsolationLevelTag:
1069+ if (nullValue)
1070+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1071+ else
1072+ rs.setTransactionIsolation(getIntegerValue(s));
1073+ break;
1074+ case KeycolsTag:
1075+ break;
1076+ case PropColumnTag:
1077+ if (keyCols == null)
1078+ keyCols = new Vector();
1079+ keyCols.add(s);
1080+ break;
1081+ case MapTag:
1082+ break;
1083+ case MaxFieldSizeTag:
1084+ if (nullValue)
1085+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1086+ else
1087+ rs.setMaxFieldSize(getIntegerValue(s));
1088+ break;
1089+ case MaxRowsTag:
1090+ if (nullValue)
1091+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1092+ else
1093+ rs.setMaxRows(getIntegerValue(s));
1094+ break;
1095+ case QueryTimeoutTag:
1096+ if (nullValue)
1097+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1098+ else
1099+ rs.setQueryTimeout(getIntegerValue(s));
1100+ break;
1101+ case ReadOnlyTag:
1102+ if (nullValue)
1103+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1104+ else
1105+ rs.setReadOnly(getBooleanValue(s));
1106+ break;
1107+ case RowsetTypeTag:
1108+ if (nullValue) {
1109+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1110+ } else {
1111+ //rs.setType(getIntegerValue(s));
1112+ String strType = getStringValue(s);
1113+ int iType = 0;
1114+
1115+ if(strType.trim().equals("ResultSet.TYPE_SCROLL_INSENSITIVE")) {
1116+ iType = 1004;
1117+ } else if(strType.trim().equals("ResultSet.TYPE_SCROLL_SENSITIVE")) {
1118+ iType = 1005;
1119+ } else if(strType.trim().equals("ResultSet.TYPE_FORWARD_ONLY")) {
1120+ iType = 1003;
1121+ }
1122+ rs.setType(iType);
1123+ }
1124+ break;
1125+ case ShowDeletedTag:
1126+ if (nullValue)
1127+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());
1128+ else
1129+ rs.setShowDeleted(getBooleanValue(s));
1130+ break;
1131+ case TableNameTag:
1132+ if (nullValue)
1133+ //rs.setTableName(null);
1134+ ;
1135+ else
1136+ rs.setTableName(s);
1137+ break;
1138+ case UrlTag:
1139+ if (nullValue)
1140+ rs.setUrl(null);
1141+ else
1142+ rs.setUrl(s);
1143+ break;
1144+ case SyncProviderNameTag:
1145+ if (nullValue) {
1146+ rs.setSyncProvider(null);
1147+ } else {
1148+ String str = s.substring(0,s.indexOf("@")+1);
1149+ rs.setSyncProvider(str);
1150+ }
1151+ break;
1152+ case SyncProviderVendorTag:
1153+ // to be implemented
1154+ break;
1155+ case SyncProviderVersionTag:
1156+ // to be implemented
1157+ break;
1158+ case SyncProviderGradeTag:
1159+ // to be implemented
1160+ break;
1161+ case DataSourceLock:
1162+ // to be implemented
1163+ break;
1164+ default:
1165+ break;
1166+ }
1167+
1168+ }
1169+
1170+ private void setMetaDataValue(String s) throws SQLException {
1171+ // find out if we are going to be dealing with a null
1172+ boolean nullValue = getNullValue();
1173+
1174+ switch (getTag()) {
1175+ case ColumnCountTag:
1176+ md = new RowSetMetaDataImpl();
1177+ idx = 0;
1178+
1179+ if (nullValue) {
1180+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1181+ } else {
1182+ md.setColumnCount(getIntegerValue(s));
1183+ }
1184+ break;
1185+ case ColumnDefinitionTag:
1186+ break;
1187+ case ColumnIndexTag:
1188+ idx++;
1189+ break;
1190+ case AutoIncrementTag:
1191+ if (nullValue)
1192+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1193+ else
1194+ md.setAutoIncrement(idx, getBooleanValue(s));
1195+ break;
1196+ case CaseSensitiveTag:
1197+ if (nullValue)
1198+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1199+ else
1200+ md.setCaseSensitive(idx, getBooleanValue(s));
1201+ break;
1202+ case CurrencyTag:
1203+ if (nullValue)
1204+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1205+ else
1206+ md.setCurrency(idx, getBooleanValue(s));
1207+ break;
1208+ case NullableTag:
1209+ if (nullValue)
1210+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1211+ else
1212+ md.setNullable(idx, getIntegerValue(s));
1213+ break;
1214+ case SignedTag:
1215+ if (nullValue)
1216+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1217+ else
1218+ md.setSigned(idx, getBooleanValue(s));
1219+ break;
1220+ case SearchableTag:
1221+ if (nullValue)
1222+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1223+ else
1224+ md.setSearchable(idx, getBooleanValue(s));
1225+ break;
1226+ case ColumnDisplaySizeTag:
1227+ if (nullValue)
1228+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1229+ else
1230+ md.setColumnDisplaySize(idx, getIntegerValue(s));
1231+ break;
1232+ case ColumnLabelTag:
1233+ if (nullValue)
1234+ md.setColumnLabel(idx, null);
1235+ else
1236+ md.setColumnLabel(idx, s);
1237+ break;
1238+ case ColumnNameTag:
1239+ if (nullValue)
1240+ md.setColumnName(idx, null);
1241+ else
1242+ md.setColumnName(idx, s);
1243+
1244+ break;
1245+ case SchemaNameTag:
1246+ if (nullValue) {
1247+ md.setSchemaName(idx, null); }
1248+ else
1249+ md.setSchemaName(idx, s);
1250+ break;
1251+ case ColumnPrecisionTag:
1252+ if (nullValue)
1253+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1254+ else
1255+ md.setPrecision(idx, getIntegerValue(s));
1256+ break;
1257+ case ColumnScaleTag:
1258+ if (nullValue)
1259+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1260+ else
1261+ md.setScale(idx, getIntegerValue(s));
1262+ break;
1263+ case MetaTableNameTag:
1264+ if (nullValue)
1265+ md.setTableName(idx, null);
1266+ else
1267+ md.setTableName(idx, s);
1268+ break;
1269+ case CatalogNameTag:
1270+ if (nullValue)
1271+ md.setCatalogName(idx, null);
1272+ else
1273+ md.setCatalogName(idx, s);
1274+ break;
1275+ case ColumnTypeTag:
1276+ if (nullValue)
1277+ throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());
1278+ else
1279+ md.setColumnType(idx, getIntegerValue(s));
1280+ break;
1281+ case ColumnTypeNameTag:
1282+ if (nullValue)
1283+ md.setColumnTypeName(idx, null);
1284+ else
1285+ md.setColumnTypeName(idx, s);
1286+ break;
1287+ default:
1288+ //System.out.println("MetaData: Unknown Tag: (" + getTag() + ")");
1289+ break;
1290+
1291+ }
1292+ }
1293+
1294+ private void setDataValue(char[] ch, int start, int len) throws SQLException {
1295+ switch (getTag()) {
1296+ case ColTag:
1297+ columnValue = new String(ch, start, len);
1298+ /**
1299+ * This has been added for handling of special characters. When special
1300+ * characters are encountered the characters function gets called for
1301+ * each of the characters so we need to append the value got in the
1302+ * previous call as it is the same data present between the start and
1303+ * the end tag.
1304+ **/
1305+ tempStr = tempStr.concat(columnValue);
1306+ break;
1307+ case UpdTag:
1308+ upd = new Object[2];
1309+
1310+ /**
1311+ * This has been added for handling of special characters. When special
1312+ * characters are encountered the characters function gets called for
1313+ * each of the characters so we need to append the value got in the
1314+ * previous call as it is the same data present between the start and
1315+ * the end tag.
1316+ **/
1317+
1318+ tempUpdate = tempUpdate.concat(new String(ch,start,len));
1319+ upd[0] = Integer.valueOf(idx);
1320+ upd[1] = tempUpdate;
1321+ //updates.add(upd);
1322+
1323+ lastval = (String)upd[1];
1324+ //insertValue(ch, start, len);
1325+ break;
1326+ case InsTag:
1327+
1328+ }
1329+ }
1330+
1331+ private void insertValue(String s) throws SQLException {
1332+
1333+ if (getNullValue()) {
1334+ rs.updateNull(idx);
1335+ return;
1336+ }
1337+
1338+ // no longer have to deal with those pesky nulls.
1339+ int type = rs.getMetaData().getColumnType(idx);
1340+ switch (type) {
1341+ case java.sql.Types.BIT:
1342+ rs.updateBoolean(idx, getBooleanValue(s));
1343+ break;
1344+ case java.sql.Types.BOOLEAN:
1345+ rs.updateBoolean(idx, getBooleanValue(s));
1346+ break;
1347+ case java.sql.Types.SMALLINT:
1348+ case java.sql.Types.TINYINT:
1349+ rs.updateShort(idx, getShortValue(s));
1350+ break;
1351+ case java.sql.Types.INTEGER:
1352+ rs.updateInt(idx, getIntegerValue(s));
1353+ break;
1354+ case java.sql.Types.BIGINT:
1355+ rs.updateLong(idx, getLongValue(s));
1356+ break;
1357+ case java.sql.Types.REAL:
1358+ case java.sql.Types.FLOAT:
1359+ rs.updateFloat(idx, getFloatValue(s));
1360+ break;
1361+ case java.sql.Types.DOUBLE:
1362+ rs.updateDouble(idx, getDoubleValue(s));
1363+ break;
1364+ case java.sql.Types.NUMERIC:
1365+ case java.sql.Types.DECIMAL:
1366+ rs.updateObject(idx, getBigDecimalValue(s));
1367+ break;
1368+ case java.sql.Types.BINARY:
1369+ case java.sql.Types.VARBINARY:
1370+ case java.sql.Types.LONGVARBINARY:
1371+ rs.updateBytes(idx, getBinaryValue(s));
1372+ break;
1373+ case java.sql.Types.DATE:
1374+ rs.updateDate(idx, getDateValue(s));
1375+ break;
1376+ case java.sql.Types.TIME:
1377+ rs.updateTime(idx, getTimeValue(s));
1378+ break;
1379+ case java.sql.Types.TIMESTAMP:
1380+ rs.updateTimestamp(idx, getTimestampValue(s));
1381+ break;
1382+ case java.sql.Types.CHAR:
1383+ case java.sql.Types.VARCHAR:
1384+ case java.sql.Types.LONGVARCHAR:
1385+ rs.updateString(idx, getStringValue(s));
1386+ break;
1387+ default:
1388+
1389+ }
1390+
1391+ }
1392+
1393+ /**
1394+ * Throws the given <code>SAXParseException</code> object. This
1395+ * exception was originally thrown by the SAX parser and is passed
1396+ * to the method <code>error</code> when the SAX parser invokes it.
1397+ *
1398+ * @param e the <code>SAXParseException</code> object to throw
1399+ */
1400+ public void error (SAXParseException e) throws SAXParseException {
1401+ throw e;
1402+ }
1403+
1404+ // dump warnings too
1405+ /**
1406+ * Prints a warning message to <code>System.out</code> giving the line
1407+ * number and uri for what caused the warning plus a message explaining
1408+ * the reason for the warning. This method is invoked by the SAX parser.
1409+ *
1410+ * @param err a warning generated by the SAX parser
1411+ */
1412+ public void warning (SAXParseException err) throws SAXParseException {
1413+ System.out.println (MessageFormat.format(resBundle.handleGetObject("xmlrch.warning").toString(), new Object[] { err.getMessage(), err.getLineNumber(), err.getSystemId() }));
1414+ }
1415+
1416+ /**
1417+ *
1418+ */
1419+ public void notationDecl(String name, String publicId, String systemId) {
1420+
1421+ }
1422+
1423+ /**
1424+ *
1425+ */
1426+ public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName) {
1427+
1428+ }
1429+
1430+ /**
1431+ * Returns the current row of this <code>Rowset</code>object.
1432+ * The ResultSet's cursor is positioned at the Row which is needed
1433+ *
1434+ * @return the <code>Row</code> object on which the <code>RowSet</code>
1435+ * implementation objects's cursor is positioned
1436+ */
1437+ private Row getPresentRow(WebRowSetImpl rs) throws SQLException {
1438+ //rs.setOriginalRow();
1439+ // ResultSetMetaData rsmd = rs.getMetaData();
1440+ // int numCols = rsmd.getColumnCount();
1441+ // Object vals[] = new Object[numCols];
1442+ // for(int j = 1; j<= numCols ; j++){
1443+ // vals[j-1] = rs.getObject(j);
1444+ // }
1445+ // return(new Row(numCols, vals));
1446+ return null;
1447+ }
1448+
1449+
1450+
1451+
1452+}