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;
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>
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
|
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;
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<Object[]>();
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<String, Integer>();
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<String, Integer>();
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<String, Integer>();
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<String,Class<?>>();
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>
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<String>();
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
|