diff -r 4ebc2e2fb97c -r 71c04702a3d5 src/java.sql.rowset/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/java.sql.rowset/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java Tue Sep 12 19:03:39 2017 +0200 @@ -0,0 +1,1454 @@ +/* + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Oracle designates this + * particular file as subject to the "Classpath" exception as provided + * by Oracle in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ + +package com.sun.rowset.internal; + +import java.util.*; + +import org.xml.sax.*; +import org.xml.sax.helpers.*; + +import java.sql.*; +import javax.sql.*; + +import javax.sql.rowset.*; +import com.sun.rowset.*; +import java.io.IOException; +import java.text.MessageFormat; + +/** + * The document handler that receives parse events that an XML parser sends while it + * is parsing an XML document representing a WebRowSet object. The + * parser sends strings to this XmlReaderContentHandler and then uses + * these strings as arguments for the XmlReaderContentHandler methods + * it invokes. The final goal of the SAX parser working with an + * XmlReaderContentHandler object is to read an XML document that represents + * a RowSet object. + *

+ * A rowset consists of its properties, metadata, and data values. An XML document + * representating a rowset includes the values in these three categories along with + * appropriate XML tags to identify them. It also includes a top-level XML tag for + * the rowset and three section tags identifying the three categories of values. + *

+ * The tags in an XML document are hierarchical. + * This means that the top-level tag, RowSet, is + * followed by the three sections with appropriate tags, which are in turn each + * followed by their constituent elements. For example, the properties + * element will be followed by an element for each of the properties listed in + * in this XmlReaderContentHandler object's properties + * field. The content of the other two fields, colDef, which lists + * the rowset's metadata elements, and data, which lists the rowset's data + * elements, are handled similarly . + *

+ * This implementation of XmlReaderContentHandler provides the means for the + * parser to determine which elements need to have a value set and then to set + * those values. The methods in this class are all called by the parser; an + * application programmer never calls them directly. + * + */ + +public class XmlReaderContentHandler extends DefaultHandler { + + private HashMap propMap; + private HashMap colDefMap; + private HashMap dataMap; + + private HashMap> typeMap; + + private Vector updates; + private Vector keyCols; + + private String columnValue; + private String propertyValue; + private String metaDataValue; + + private int tag; + private int state; + + private WebRowSetImpl rs; + private boolean nullVal; + private boolean emptyStringVal; + private RowSetMetaData md; + private int idx; + private String lastval; + private String Key_map; + private String Value_map; + private String tempStr; + private String tempUpdate; + private String tempCommand; + private Object [] upd; + + /** + * A list of the properties for a rowset. There is a constant defined to + * correspond to each of these properties so that a HashMap + * object can be created to map the properties, which are strings, to + * the constants, which are integers. + */ + private String [] properties = {"command", "concurrency", "datasource", + "escape-processing", "fetch-direction", "fetch-size", + "isolation-level", "key-columns", "map", + "max-field-size", "max-rows", "query-timeout", + "read-only", "rowset-type", "show-deleted", + "table-name", "url", "null", "column", "type", + "class", "sync-provider", "sync-provider-name", + "sync-provider-vendor", "sync-provider-version", + "sync-provider-grade","data-source-lock"}; + + /** + * A constant representing the tag for the command property. + */ + private final static int CommandTag = 0; + + /** + * A constant representing the tag for the concurrency property. + */ + private final static int ConcurrencyTag = 1; + + /** + * A constant representing the tag for the datasource property. + */ + private final static int DatasourceTag = 2; + + /** + * A constant representing the tag for the escape-processing property. + */ + private final static int EscapeProcessingTag = 3; + + /** + * A constant representing the tag for the fetch-direction property. + */ + private final static int FetchDirectionTag = 4; + + /** + * A constant representing the tag for the fetch-size property. + */ + private final static int FetchSizeTag = 5; + + /** + * A constant representing the tag for the isolation-level property + */ + private final static int IsolationLevelTag = 6; + + /** + * A constant representing the tag for the key-columns property. + */ + private final static int KeycolsTag = 7; + + /** + * A constant representing the tag for the map property. + * This map is the type map that specifies the custom mapping + * for an SQL user-defined type. + */ + private final static int MapTag = 8; + + /** + * A constant representing the tag for the max-field-size property. + */ + private final static int MaxFieldSizeTag = 9; + + /** + * A constant representing the tag for the max-rows property. + */ + private final static int MaxRowsTag = 10; + + /** + * A constant representing the tag for the query-timeout property. + */ + private final static int QueryTimeoutTag = 11; + + /** + * A constant representing the tag for the read-only property. + */ + private final static int ReadOnlyTag = 12; + + /** + * A constant representing the tag for the rowset-type property. + */ + private final static int RowsetTypeTag = 13; + + /** + * A constant representing the tag for the show-deleted property. + */ + private final static int ShowDeletedTag = 14; + + /** + * A constant representing the tag for the table-name property. + */ + private final static int TableNameTag = 15; + + /** + * A constant representing the tag for the URL property. + */ + private final static int UrlTag = 16; + + /** + * A constant representing the tag for the null property. + */ + private final static int PropNullTag = 17; + + /** + * A constant representing the tag for the column property. + */ + private final static int PropColumnTag = 18; + + /** + * A constant representing the tag for the type property. + */ + private final static int PropTypeTag = 19; + + /** + * A constant representing the tag for the class property. + */ + private final static int PropClassTag = 20; + + /** + * A constant representing the tag for the sync-provider. + */ + private final static int SyncProviderTag = 21; + + /** + * A constant representing the tag for the sync-provider + * name + */ + private final static int SyncProviderNameTag = 22; + + /** + * A constant representing the tag for the sync-provider + * vendor tag. + */ + private final static int SyncProviderVendorTag = 23; + + /** + * A constant representing the tag for the sync-provider + * version tag. + */ + private final static int SyncProviderVersionTag = 24; + + /** + * A constant representing the tag for the sync-provider + * grade tag. + */ + private final static int SyncProviderGradeTag = 25; + + /** + * A constant representing the tag for the data source lock. + */ + private final static int DataSourceLock = 26; + + /** + * A listing of the kinds of metadata information available about + * the columns in a WebRowSet object. + */ + private String [] colDef = {"column-count", "column-definition", "column-index", + "auto-increment", "case-sensitive", "currency", + "nullable", "signed", "searchable", + "column-display-size", "column-label", "column-name", + "schema-name", "column-precision", "column-scale", + "table-name", "catalog-name", "column-type", + "column-type-name", "null"}; + + + /** + * A constant representing the tag for column-count. + */ + private final static int ColumnCountTag = 0; + + /** + * A constant representing the tag for column-definition. + */ + private final static int ColumnDefinitionTag = 1; + + /** + * A constant representing the tag for column-index. + */ + private final static int ColumnIndexTag = 2; + + /** + * A constant representing the tag for auto-increment. + */ + private final static int AutoIncrementTag = 3; + + /** + * A constant representing the tag for case-sensitive. + */ + private final static int CaseSensitiveTag = 4; + + /** + * A constant representing the tag for currency. + */ + private final static int CurrencyTag = 5; + + /** + * A constant representing the tag for nullable. + */ + private final static int NullableTag = 6; + + /** + * A constant representing the tag for signed. + */ + private final static int SignedTag = 7; + + /** + * A constant representing the tag for searchable. + */ + private final static int SearchableTag = 8; + + /** + * A constant representing the tag for column-display-size. + */ + private final static int ColumnDisplaySizeTag = 9; + + /** + * A constant representing the tag for column-label. + */ + private final static int ColumnLabelTag = 10; + + /** + * A constant representing the tag for column-name. + */ + private final static int ColumnNameTag = 11; + + /** + * A constant representing the tag for schema-name. + */ + private final static int SchemaNameTag = 12; + + /** + * A constant representing the tag for column-precision. + */ + private final static int ColumnPrecisionTag = 13; + + /** + * A constant representing the tag for column-scale. + */ + private final static int ColumnScaleTag = 14; + + /** + * A constant representing the tag for table-name. + */ + private final static int MetaTableNameTag = 15; + + /** + * A constant representing the tag for catalog-name. + */ + private final static int CatalogNameTag = 16; + + /** + * A constant representing the tag for column-type. + */ + private final static int ColumnTypeTag = 17; + + /** + * A constant representing the tag for column-type-name. + */ + private final static int ColumnTypeNameTag = 18; + + /** + * A constant representing the tag for null. + */ + private final static int MetaNullTag = 19; + + private String [] data = {"currentRow", "columnValue", "insertRow", "deleteRow", "insdel", "updateRow", "null" , "emptyString"}; + + private final static int RowTag = 0; + private final static int ColTag = 1; + private final static int InsTag = 2; + private final static int DelTag = 3; + private final static int InsDelTag = 4; + private final static int UpdTag = 5; + private final static int NullTag = 6; + private final static int EmptyStringTag = 7; + + /** + * A constant indicating the state of this XmlReaderContentHandler + * object in which it has not yet been called by the SAX parser and therefore + * has no indication of what type of input to expect from the parser next. + *

+ * The state is set to INITIAL at the end of each + * section, which allows the sections to appear in any order and + * still be parsed correctly (except that metadata must be + * set before data values can be set). + */ + private final static int INITIAL = 0; + + /** + * A constant indicating the state in which this XmlReaderContentHandler + * object expects the next input received from the + * SAX parser to be a string corresponding to one of the elements in + * properties. + */ + private final static int PROPERTIES = 1; + + /** + * A constant indicating the state in which this XmlReaderContentHandler + * object expects the next input received from the + * SAX parser to be a string corresponding to one of the elements in + * colDef. + */ + private final static int METADATA = 2; + + /** + * A constant indicating the state in which this XmlReaderContentHandler + * object expects the next input received from the + * SAX parser to be a string corresponding to one of the elements in + * data. + */ + private final static int DATA = 3; + + private JdbcRowSetResourceBundle resBundle; + + /** + * Constructs a new XmlReaderContentHandler object that will + * assist the SAX parser in reading a WebRowSet object in the + * format of an XML document. In addition to setting some default values, + * this constructor creates three HashMap objects, one for + * properties, one for metadata, and one for data. These hash maps map the + * strings sent by the SAX parser to integer constants so that they can be + * compared more efficiently in switch statements. + * + * @param r the RowSet object in XML format that will be read + */ + public XmlReaderContentHandler(RowSet r) { + // keep the rowset we've been given + rs = (WebRowSetImpl)r; + + // set-up the token maps + initMaps(); + + // allocate the collection for the updates + updates = new Vector<>(); + + // start out with the empty string + columnValue = ""; + propertyValue = ""; + metaDataValue = ""; + + nullVal = false; + idx = 0; + tempStr = ""; + tempUpdate = ""; + tempCommand = ""; + + try { + resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle(); + } catch(IOException ioe) { + throw new RuntimeException(ioe); + } + } + + /** + * Creates and initializes three new HashMap objects that map + * the strings returned by the SAX parser to Integer + * objects. The strings returned by the parser will match the strings that + * are array elements in this XmlReaderContentHandler object's + * properties, colDef, or data + * fields. For each array element in these fields, there is a corresponding + * constant defined. It is to these constants that the strings are mapped. + * In the HashMap objects, the string is the key, and the + * integer is the value. + *

+ * The purpose of the mapping is to make comparisons faster. Because comparing + * numbers is more efficient than comparing strings, the strings returned + * by the parser are mapped to integers, which can then be used in a + * switch statement. + */ + private void initMaps() { + int items, i; + + propMap = new HashMap<>(); + items = properties.length; + + for (i=0;i(); + items = colDef.length; + + for (i=0;i(); + items = data.length; + + for (i=0;i(); + } + + public void startDocument() throws SAXException { + } + + public void endDocument() throws SAXException { + } + + + /** + * Sets this XmlReaderContentHandler object's tag + * field if the given name is the key for a tag and this object's state + * is not INITIAL. The field is set + * to the constant that corresponds to the given element name. + * If the state is INITIAL, the state is set to the given + * name, which will be one of the sections PROPERTIES, + * METADATA, or DATA. In either case, this + * method puts this document handler in the proper state for calling + * the method endElement. + *

+ * If the state is DATA and the tag is RowTag, + * DelTag, or InsTag, this method moves the + * rowset's cursor to the insert row and sets this + * XmlReaderContentHandler object's idx + * field to 0 so that it will be in the proper + * state when the parser calls the method endElement. + * + * @param lName the name of the element; either (1) one of the array + * elements in the fields properties, + * colDef, or data or + * (2) one of the RowSet elements + * "properties", "metadata", or + * "data" + * @param attributes org.xml.sax.AttributeList objects that are + * attributes of the named section element; may be null + * if there are no attributes, which is the case for + * WebRowSet objects + * @exception SAXException if a general SAX error occurs + */ + public void startElement(String uri, String lName, String qName, Attributes attributes) throws SAXException { + int tag; + String name = ""; + + name = lName; + + switch (getState()) { + case PROPERTIES: + + tempCommand = ""; + tag = propMap.get(name); + if (tag == PropNullTag) + setNullValue(true); + else + setTag(tag); + break; + case METADATA: + tag = colDefMap.get(name); + + if (tag == MetaNullTag) + setNullValue(true); + else + setTag(tag); + break; + case DATA: + + /** + * This has been added to clear out the values of the previous read + * so that we should not add up values of data between different tags + */ + tempStr = ""; + tempUpdate = ""; + if(dataMap.get(name) == null) { + tag = NullTag; + } else if(dataMap.get(name) == EmptyStringTag) { + tag = EmptyStringTag; + } else { + tag = dataMap.get(name); + } + + if (tag == NullTag) { + setNullValue(true); + } else if(tag == EmptyStringTag) { + setEmptyStringValue(true); + } else { + setTag(tag); + + if (tag == RowTag || tag == DelTag || tag == InsTag) { + idx = 0; + try { + rs.moveToInsertRow(); + } catch (SQLException ex) { + ; + } + } + } + + break; + default: + setState(name); + } + + } + + /** + * Sets the value for the given element if name is one of + * the array elements in the fields properties, + * colDef, or data and this + * XmlReaderContentHandler object's state is not + * INITIAL. If the state is INITIAL, + * this method does nothing. + *

+ * If the state is METADATA and + * the argument supplied is "metadata", the rowset's + * metadata is set. If the state is PROPERTIES, the + * appropriate property is set using the given name to determine + * the appropriate value. If the state is DATA and + * the argument supplied is "data", this method sets + * the state to INITIAL and returns. If the argument + * supplied is one of the elements in the field data, + * this method makes the appropriate changes to the rowset's data. + * + * @param lName the name of the element; either (1) one of the array + * elements in the fields properties, + * colDef, or data or + * (2) one of the RowSet elements + * "properties", "metadata", or + * "data" + * + * @exception SAXException if a general SAX error occurs + */ + @SuppressWarnings("fallthrough") + public void endElement(String uri, String lName, String qName) throws SAXException { + int tag; + + String name = ""; + name = lName; + + switch (getState()) { + case PROPERTIES: + if (name.equals("properties")) { + state = INITIAL; + break; + } + + try { + tag = propMap.get(name); + switch (tag) { + case KeycolsTag: + if (keyCols != null) { + int i[] = new int[keyCols.size()]; + for (int j = 0; j < i.length; j++) + i[j] = Integer.parseInt(keyCols.elementAt(j)); + rs.setKeyColumns(i); + } + break; + + case PropClassTag: + //Added the handling for Class tags to take care of maps + //Makes an entry into the map upon end of class tag + try{ + typeMap.put(Key_map,sun.reflect.misc.ReflectUtil.forName(Value_map)); + + }catch(ClassNotFoundException ex) { + throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errmap").toString(), ex.getMessage())); + } + break; + + case MapTag: + //Added the handling for Map to take set the typeMap + rs.setTypeMap(typeMap); + break; + + default: + break; + } + + if (getNullValue()) { + setPropertyValue(null); + setNullValue(false); + } else { + setPropertyValue(propertyValue); + } + } catch (SQLException ex) { + throw new SAXException(ex.getMessage()); + } + + // propertyValue need to be reset to an empty string + propertyValue = ""; + setTag(-1); + break; + case METADATA: + if (name.equals("metadata")) { + try { + rs.setMetaData(md); + state = INITIAL; + } catch (SQLException ex) { + throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errmetadata").toString(), ex.getMessage())); + } + } else { + try { + if (getNullValue()) { + setMetaDataValue(null); + setNullValue(false); + } else { + setMetaDataValue(metaDataValue); + } + } catch (SQLException ex) { + throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errmetadata").toString(), ex.getMessage())); + + } + // metaDataValue needs to be reset to an empty string + metaDataValue = ""; + } + setTag(-1); + break; + case DATA: + if (name.equals("data")) { + state = INITIAL; + return; + } + + if(dataMap.get(name) == null) { + tag = NullTag; + } else { + tag = dataMap.get(name); + } + switch (tag) { + case ColTag: + try { + idx++; + if (getNullValue()) { + insertValue(null); + setNullValue(false); + } else { + insertValue(tempStr); + } + // columnValue now need to be reset to the empty string + columnValue = ""; + } catch (SQLException ex) { + throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsertval").toString(), ex.getMessage())); + } + break; + case RowTag: + try { + rs.insertRow(); + rs.moveToCurrentRow(); + rs.next(); + + // Making this as the original to turn off the + // rowInserted flagging + rs.setOriginalRow(); + + applyUpdates(); + } catch (SQLException ex) { + throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errconstr").toString(), ex.getMessage())); + } + break; + case DelTag: + try { + rs.insertRow(); + rs.moveToCurrentRow(); + rs.next(); + rs.setOriginalRow(); + applyUpdates(); + rs.deleteRow(); + } catch (SQLException ex) { + throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errdel").toString() , ex.getMessage())); + } + break; + case InsTag: + try { + rs.insertRow(); + rs.moveToCurrentRow(); + rs.next(); + applyUpdates(); + } catch (SQLException ex) { + throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsert").toString() , ex.getMessage())); + } + break; + + case InsDelTag: + try { + rs.insertRow(); + rs.moveToCurrentRow(); + rs.next(); + rs.setOriginalRow(); + applyUpdates(); + } catch (SQLException ex) { + throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsdel").toString() , ex.getMessage())); + } + break; + + case UpdTag: + try { + if(getNullValue()) + { + insertValue(null); + setNullValue(false); + } else if(getEmptyStringValue()) { + insertValue(""); + setEmptyStringValue(false); + } else { + updates.add(upd); + } + } catch(SQLException ex) { + throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errupdate").toString() , ex.getMessage())); + } + break; + + default: + break; + } + default: + break; + } + } + + private void applyUpdates() throws SAXException { + // now handle any updates + if (updates.size() > 0) { + try { + Object upd[]; + Iterator i = updates.iterator(); + while (i.hasNext()) { + upd = (Object [])i.next(); + idx = ((Integer)upd[0]).intValue(); + + if(!(lastval.equals(upd[1]))){ + insertValue((String)(upd[1])); + } + } + + rs.updateRow(); + } catch (SQLException ex) { + throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errupdrow").toString() , ex.getMessage())); + } + updates.removeAllElements(); + } + + + } + + /** + * Sets a property, metadata, or data value with the characters in + * the given array of characters, starting with the array element + * indicated by start and continuing for length + * number of characters. + *

+ * The SAX parser invokes this method and supplies + * the character array, start position, and length parameter values it + * got from parsing the XML document. An application programmer never + * invokes this method directly. + * + * @param ch an array of characters supplied by the SAX parser, all or part of + * which will be used to set a value + * @param start the position in the given array at which to start + * @param length the number of consecutive characters to use + */ + public void characters(char[] ch, int start, int length) throws SAXException { + try { + switch (getState()) { + case PROPERTIES: + propertyValue = new String(ch, start, length); + + /** + * This has been added for handling of special characters. When special + * characters are encountered the characters function gets called for + * each of the characters so we need to append the value got in the + * previous call as it is the same data present between the start and + * the end tag. + **/ + tempCommand = tempCommand.concat(propertyValue); + propertyValue = tempCommand; + + // Added the following check for handling of type tags in maps + if(tag == PropTypeTag) + { + Key_map = propertyValue; + } + + // Added the following check for handling of class tags in maps + else if(tag == PropClassTag) + { + Value_map = propertyValue; + } + break; + + case METADATA: + + // The parser will come here after the endElement as there is + // "\n" in the after endTag is printed. This will cause a problem + // when the data between the tags is an empty string so adding + // below condition to take care of that situation. + + if (tag == -1) + { + break; + } + + metaDataValue = new String(ch, start, length); + break; + case DATA: + setDataValue(ch, start, length); + break; + default: + ; + } + } catch (SQLException ex) { + throw new SAXException(resBundle.handleGetObject("xmlrch.chars").toString() + ex.getMessage()); + } + } + + private void setState(String s) throws SAXException { + if (s.equals("webRowSet")) { + state = INITIAL; + } else if (s.equals("properties")) { + if (state != PROPERTIES) + state = PROPERTIES; + else + state = INITIAL; + } else if (s.equals("metadata")) { + if (state != METADATA) + state = METADATA; + else + state = INITIAL; + } else if (s.equals("data")) { + if (state != DATA) + state = DATA; + else + state = INITIAL; + } + + } + + /** + * Retrieves the current state of this XmlReaderContentHandler + * object's rowset, which is stored in the document handler's + * state field. + * + * @return one of the following constants: + * XmlReaderContentHandler.PROPERTIES + * XmlReaderContentHandler.METADATA + * XmlReaderContentHandler.DATA + * XmlReaderContentHandler.INITIAL + */ + private int getState() { + return state; + } + + private void setTag(int t) { + tag = t; + } + + private int getTag() { + return tag; + } + + private void setNullValue(boolean n) { + nullVal = n; + } + + private boolean getNullValue() { + return nullVal; + } + + private void setEmptyStringValue(boolean e) { + emptyStringVal = e; + } + + private boolean getEmptyStringValue() { + return emptyStringVal; + } + + private String getStringValue(String s) { + return s; + } + + private int getIntegerValue(String s) { + return Integer.parseInt(s); + } + + private boolean getBooleanValue(String s) { + + return Boolean.valueOf(s).booleanValue(); + } + + private java.math.BigDecimal getBigDecimalValue(String s) { + return new java.math.BigDecimal(s); + } + + private byte getByteValue(String s) { + return Byte.parseByte(s); + } + + private short getShortValue(String s) { + return Short.parseShort(s); + } + + private long getLongValue(String s) { + return Long.parseLong(s); + } + + private float getFloatValue(String s) { + return Float.parseFloat(s); + } + + private double getDoubleValue(String s) { + return Double.parseDouble(s); + } + + private byte[] getBinaryValue(String s) { + return s.getBytes(); + } + + private java.sql.Date getDateValue(String s) { + return new java.sql.Date(getLongValue(s)); + } + + private java.sql.Time getTimeValue(String s) { + return new java.sql.Time(getLongValue(s)); + } + + private java.sql.Timestamp getTimestampValue(String s) { + return new java.sql.Timestamp(getLongValue(s)); + } + + private void setPropertyValue(String s) throws SQLException { + // find out if we are going to be dealing with a null + boolean nullValue = getNullValue(); + + switch(getTag()) { + case CommandTag: + if (nullValue) + ; //rs.setCommand(null); + else + rs.setCommand(s); + break; + case ConcurrencyTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString()); + else + rs.setConcurrency(getIntegerValue(s)); + break; + case DatasourceTag: + if (nullValue) + rs.setDataSourceName(null); + else + rs.setDataSourceName(s); + break; + case EscapeProcessingTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString()); + else + rs.setEscapeProcessing(getBooleanValue(s)); + break; + case FetchDirectionTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString()); + else + rs.setFetchDirection(getIntegerValue(s)); + break; + case FetchSizeTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString()); + else + rs.setFetchSize(getIntegerValue(s)); + break; + case IsolationLevelTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString()); + else + rs.setTransactionIsolation(getIntegerValue(s)); + break; + case KeycolsTag: + break; + case PropColumnTag: + if (keyCols == null) + keyCols = new Vector<>(); + keyCols.add(s); + break; + case MapTag: + break; + case MaxFieldSizeTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString()); + else + rs.setMaxFieldSize(getIntegerValue(s)); + break; + case MaxRowsTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString()); + else + rs.setMaxRows(getIntegerValue(s)); + break; + case QueryTimeoutTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString()); + else + rs.setQueryTimeout(getIntegerValue(s)); + break; + case ReadOnlyTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString()); + else + rs.setReadOnly(getBooleanValue(s)); + break; + case RowsetTypeTag: + if (nullValue) { + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString()); + } else { + //rs.setType(getIntegerValue(s)); + String strType = getStringValue(s); + int iType = 0; + + if(strType.trim().equals("ResultSet.TYPE_SCROLL_INSENSITIVE")) { + iType = 1004; + } else if(strType.trim().equals("ResultSet.TYPE_SCROLL_SENSITIVE")) { + iType = 1005; + } else if(strType.trim().equals("ResultSet.TYPE_FORWARD_ONLY")) { + iType = 1003; + } + rs.setType(iType); + } + break; + case ShowDeletedTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString()); + else + rs.setShowDeleted(getBooleanValue(s)); + break; + case TableNameTag: + if (nullValue) + //rs.setTableName(null); + ; + else + rs.setTableName(s); + break; + case UrlTag: + if (nullValue) + rs.setUrl(null); + else + rs.setUrl(s); + break; + case SyncProviderNameTag: + if (nullValue) { + rs.setSyncProvider(null); + } else { + String str = s.substring(0,s.indexOf('@')+1); + rs.setSyncProvider(str); + } + break; + case SyncProviderVendorTag: + // to be implemented + break; + case SyncProviderVersionTag: + // to be implemented + break; + case SyncProviderGradeTag: + // to be implemented + break; + case DataSourceLock: + // to be implemented + break; + default: + break; + } + + } + + private void setMetaDataValue(String s) throws SQLException { + // find out if we are going to be dealing with a null + boolean nullValue = getNullValue(); + + switch (getTag()) { + case ColumnCountTag: + md = new RowSetMetaDataImpl(); + idx = 0; + + if (nullValue) { + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString()); + } else { + md.setColumnCount(getIntegerValue(s)); + } + break; + case ColumnDefinitionTag: + break; + case ColumnIndexTag: + idx++; + break; + case AutoIncrementTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString()); + else + md.setAutoIncrement(idx, getBooleanValue(s)); + break; + case CaseSensitiveTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString()); + else + md.setCaseSensitive(idx, getBooleanValue(s)); + break; + case CurrencyTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString()); + else + md.setCurrency(idx, getBooleanValue(s)); + break; + case NullableTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString()); + else + md.setNullable(idx, getIntegerValue(s)); + break; + case SignedTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString()); + else + md.setSigned(idx, getBooleanValue(s)); + break; + case SearchableTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString()); + else + md.setSearchable(idx, getBooleanValue(s)); + break; + case ColumnDisplaySizeTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString()); + else + md.setColumnDisplaySize(idx, getIntegerValue(s)); + break; + case ColumnLabelTag: + if (nullValue) + md.setColumnLabel(idx, null); + else + md.setColumnLabel(idx, s); + break; + case ColumnNameTag: + if (nullValue) + md.setColumnName(idx, null); + else + md.setColumnName(idx, s); + + break; + case SchemaNameTag: + if (nullValue) { + md.setSchemaName(idx, null); } + else + md.setSchemaName(idx, s); + break; + case ColumnPrecisionTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString()); + else + md.setPrecision(idx, getIntegerValue(s)); + break; + case ColumnScaleTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString()); + else + md.setScale(idx, getIntegerValue(s)); + break; + case MetaTableNameTag: + if (nullValue) + md.setTableName(idx, null); + else + md.setTableName(idx, s); + break; + case CatalogNameTag: + if (nullValue) + md.setCatalogName(idx, null); + else + md.setCatalogName(idx, s); + break; + case ColumnTypeTag: + if (nullValue) + throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString()); + else + md.setColumnType(idx, getIntegerValue(s)); + break; + case ColumnTypeNameTag: + if (nullValue) + md.setColumnTypeName(idx, null); + else + md.setColumnTypeName(idx, s); + break; + default: + //System.out.println("MetaData: Unknown Tag: (" + getTag() + ")"); + break; + + } + } + + private void setDataValue(char[] ch, int start, int len) throws SQLException { + switch (getTag()) { + case ColTag: + columnValue = new String(ch, start, len); + /** + * This has been added for handling of special characters. When special + * characters are encountered the characters function gets called for + * each of the characters so we need to append the value got in the + * previous call as it is the same data present between the start and + * the end tag. + **/ + tempStr = tempStr.concat(columnValue); + break; + case UpdTag: + upd = new Object[2]; + + /** + * This has been added for handling of special characters. When special + * characters are encountered the characters function gets called for + * each of the characters so we need to append the value got in the + * previous call as it is the same data present between the start and + * the end tag. + **/ + + tempUpdate = tempUpdate.concat(new String(ch,start,len)); + upd[0] = Integer.valueOf(idx); + upd[1] = tempUpdate; + //updates.add(upd); + + lastval = (String)upd[1]; + //insertValue(ch, start, len); + break; + case InsTag: + + } + } + + private void insertValue(String s) throws SQLException { + + if (getNullValue()) { + rs.updateNull(idx); + return; + } + + // no longer have to deal with those pesky nulls. + int type = rs.getMetaData().getColumnType(idx); + switch (type) { + case java.sql.Types.BIT: + rs.updateBoolean(idx, getBooleanValue(s)); + break; + case java.sql.Types.BOOLEAN: + rs.updateBoolean(idx, getBooleanValue(s)); + break; + case java.sql.Types.SMALLINT: + case java.sql.Types.TINYINT: + rs.updateShort(idx, getShortValue(s)); + break; + case java.sql.Types.INTEGER: + rs.updateInt(idx, getIntegerValue(s)); + break; + case java.sql.Types.BIGINT: + rs.updateLong(idx, getLongValue(s)); + break; + case java.sql.Types.REAL: + case java.sql.Types.FLOAT: + rs.updateFloat(idx, getFloatValue(s)); + break; + case java.sql.Types.DOUBLE: + rs.updateDouble(idx, getDoubleValue(s)); + break; + case java.sql.Types.NUMERIC: + case java.sql.Types.DECIMAL: + rs.updateObject(idx, getBigDecimalValue(s)); + break; + case java.sql.Types.BINARY: + case java.sql.Types.VARBINARY: + case java.sql.Types.LONGVARBINARY: + rs.updateBytes(idx, getBinaryValue(s)); + break; + case java.sql.Types.DATE: + rs.updateDate(idx, getDateValue(s)); + break; + case java.sql.Types.TIME: + rs.updateTime(idx, getTimeValue(s)); + break; + case java.sql.Types.TIMESTAMP: + rs.updateTimestamp(idx, getTimestampValue(s)); + break; + case java.sql.Types.CHAR: + case java.sql.Types.VARCHAR: + case java.sql.Types.LONGVARCHAR: + rs.updateString(idx, getStringValue(s)); + break; + default: + + } + + } + + /** + * Throws the given SAXParseException object. This + * exception was originally thrown by the SAX parser and is passed + * to the method error when the SAX parser invokes it. + * + * @param e the SAXParseException object to throw + */ + public void error (SAXParseException e) throws SAXParseException { + throw e; + } + + // dump warnings too + /** + * Prints a warning message to System.out giving the line + * number and uri for what caused the warning plus a message explaining + * the reason for the warning. This method is invoked by the SAX parser. + * + * @param err a warning generated by the SAX parser + */ + public void warning (SAXParseException err) throws SAXParseException { + System.out.println (MessageFormat.format(resBundle.handleGetObject("xmlrch.warning").toString(), new Object[] { err.getMessage(), err.getLineNumber(), err.getSystemId() })); + } + + /** + * + */ + public void notationDecl(String name, String publicId, String systemId) { + + } + + /** + * + */ + public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName) { + + } + + /** + * Returns the current row of this Rowsetobject. + * The ResultSet's cursor is positioned at the Row which is needed + * + * @return the Row object on which the RowSet + * implementation objects's cursor is positioned + */ + private Row getPresentRow(WebRowSetImpl rs) throws SQLException { + //rs.setOriginalRow(); + // ResultSetMetaData rsmd = rs.getMetaData(); + // int numCols = rsmd.getColumnCount(); + // Object vals[] = new Object[numCols]; + // for(int j = 1; j<= numCols ; j++){ + // vals[j-1] = rs.getObject(j); + // } + // return(new Row(numCols, vals)); + return null; + } + + + + +}