Path: blob/master/src/java.sql.rowset/share/classes/com/sun/rowset/internal/XmlReaderContentHandler.java
40948 views
/*1* Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.sun.rowset.internal;2627import java.util.*;2829import org.xml.sax.*;30import org.xml.sax.helpers.*;3132import java.sql.*;33import javax.sql.*;3435import javax.sql.rowset.*;36import com.sun.rowset.*;37import java.io.IOException;38import java.text.MessageFormat;3940/**41* The document handler that receives parse events that an XML parser sends while it42* is parsing an XML document representing a <code>WebRowSet</code> object. The43* parser sends strings to this <code>XmlReaderContentHandler</code> and then uses44* these strings as arguments for the <code>XmlReaderContentHandler</code> methods45* it invokes. The final goal of the SAX parser working with an46* <code>XmlReaderContentHandler</code> object is to read an XML document that represents47* a <code>RowSet</code> object.48* <P>49* A rowset consists of its properties, metadata, and data values. An XML document50* representating a rowset includes the values in these three categories along with51* appropriate XML tags to identify them. It also includes a top-level XML tag for52* the rowset and three section tags identifying the three categories of values.53* <P>54* The tags in an XML document are hierarchical.55* This means that the top-level tag, <code>RowSet</code>, is56* followed by the three sections with appropriate tags, which are in turn each57* followed by their constituent elements. For example, the <code>properties</code>58* element will be followed by an element for each of the properties listed in59* in this <code>XmlReaderContentHandler</code> object's <code>properties</code>60* field. The content of the other two fields, <code>colDef</code>, which lists61* the rowset's metadata elements, and <code>data</code>, which lists the rowset's data62* elements, are handled similarly .63* <P>64* This implementation of <code>XmlReaderContentHandler</code> provides the means for the65* parser to determine which elements need to have a value set and then to set66* those values. The methods in this class are all called by the parser; an67* application programmer never calls them directly.68*69*/7071public class XmlReaderContentHandler extends DefaultHandler {7273private HashMap <String, Integer> propMap;74private HashMap <String, Integer> colDefMap;75private HashMap <String, Integer> dataMap;7677private HashMap<String,Class<?>> typeMap;7879private Vector<Object[]> updates;80private Vector<String> keyCols;8182private String columnValue;83private String propertyValue;84private String metaDataValue;8586private int tag;87private int state;8889private WebRowSetImpl rs;90private boolean nullVal;91private boolean emptyStringVal;92private RowSetMetaData md;93private int idx;94private String lastval;95private String Key_map;96private String Value_map;97private String tempStr;98private String tempUpdate;99private String tempCommand;100private Object [] upd;101102/**103* A list of the properties for a rowset. There is a constant defined to104* correspond to each of these properties so that a <code>HashMap</code>105* object can be created to map the properties, which are strings, to106* the constants, which are integers.107*/108private String [] properties = {"command", "concurrency", "datasource",109"escape-processing", "fetch-direction", "fetch-size",110"isolation-level", "key-columns", "map",111"max-field-size", "max-rows", "query-timeout",112"read-only", "rowset-type", "show-deleted",113"table-name", "url", "null", "column", "type",114"class", "sync-provider", "sync-provider-name",115"sync-provider-vendor", "sync-provider-version",116"sync-provider-grade","data-source-lock"};117118/**119* A constant representing the tag for the command property.120*/121private static final int CommandTag = 0;122123/**124* A constant representing the tag for the concurrency property.125*/126private static final int ConcurrencyTag = 1;127128/**129* A constant representing the tag for the datasource property.130*/131private static final int DatasourceTag = 2;132133/**134* A constant representing the tag for the escape-processing property.135*/136private static final int EscapeProcessingTag = 3;137138/**139* A constant representing the tag for the fetch-direction property.140*/141private static final int FetchDirectionTag = 4;142143/**144* A constant representing the tag for the fetch-size property.145*/146private static final int FetchSizeTag = 5;147148/**149* A constant representing the tag for the isolation-level property150*/151private static final int IsolationLevelTag = 6;152153/**154* A constant representing the tag for the key-columns property.155*/156private static final int KeycolsTag = 7;157158/**159* A constant representing the tag for the map property.160* This map is the type map that specifies the custom mapping161* for an SQL user-defined type.162*/163private static final int MapTag = 8;164165/**166* A constant representing the tag for the max-field-size property.167*/168private static final int MaxFieldSizeTag = 9;169170/**171* A constant representing the tag for the max-rows property.172*/173private static final int MaxRowsTag = 10;174175/**176* A constant representing the tag for the query-timeout property.177*/178private static final int QueryTimeoutTag = 11;179180/**181* A constant representing the tag for the read-only property.182*/183private static final int ReadOnlyTag = 12;184185/**186* A constant representing the tag for the rowset-type property.187*/188private static final int RowsetTypeTag = 13;189190/**191* A constant representing the tag for the show-deleted property.192*/193private static final int ShowDeletedTag = 14;194195/**196* A constant representing the tag for the table-name property.197*/198private static final int TableNameTag = 15;199200/**201* A constant representing the tag for the URL property.202*/203private static final int UrlTag = 16;204205/**206* A constant representing the tag for the null property.207*/208private static final int PropNullTag = 17;209210/**211* A constant representing the tag for the column property.212*/213private static final int PropColumnTag = 18;214215/**216* A constant representing the tag for the type property.217*/218private static final int PropTypeTag = 19;219220/**221* A constant representing the tag for the class property.222*/223private static final int PropClassTag = 20;224225/**226* A constant representing the tag for the sync-provider.227*/228private static final int SyncProviderTag = 21;229230/**231* A constant representing the tag for the sync-provider232* name233*/234private static final int SyncProviderNameTag = 22;235236/**237* A constant representing the tag for the sync-provider238* vendor tag.239*/240private static final int SyncProviderVendorTag = 23;241242/**243* A constant representing the tag for the sync-provider244* version tag.245*/246private static final int SyncProviderVersionTag = 24;247248/**249* A constant representing the tag for the sync-provider250* grade tag.251*/252private static final int SyncProviderGradeTag = 25;253254/**255* A constant representing the tag for the data source lock.256*/257private static final int DataSourceLock = 26;258259/**260* A listing of the kinds of metadata information available about261* the columns in a <code>WebRowSet</code> object.262*/263private String [] colDef = {"column-count", "column-definition", "column-index",264"auto-increment", "case-sensitive", "currency",265"nullable", "signed", "searchable",266"column-display-size", "column-label", "column-name",267"schema-name", "column-precision", "column-scale",268"table-name", "catalog-name", "column-type",269"column-type-name", "null"};270271272/**273* A constant representing the tag for column-count.274*/275private static final int ColumnCountTag = 0;276277/**278* A constant representing the tag for column-definition.279*/280private static final int ColumnDefinitionTag = 1;281282/**283* A constant representing the tag for column-index.284*/285private static final int ColumnIndexTag = 2;286287/**288* A constant representing the tag for auto-increment.289*/290private static final int AutoIncrementTag = 3;291292/**293* A constant representing the tag for case-sensitive.294*/295private static final int CaseSensitiveTag = 4;296297/**298* A constant representing the tag for currency.299*/300private static final int CurrencyTag = 5;301302/**303* A constant representing the tag for nullable.304*/305private static final int NullableTag = 6;306307/**308* A constant representing the tag for signed.309*/310private static final int SignedTag = 7;311312/**313* A constant representing the tag for searchable.314*/315private static final int SearchableTag = 8;316317/**318* A constant representing the tag for column-display-size.319*/320private static final int ColumnDisplaySizeTag = 9;321322/**323* A constant representing the tag for column-label.324*/325private static final int ColumnLabelTag = 10;326327/**328* A constant representing the tag for column-name.329*/330private static final int ColumnNameTag = 11;331332/**333* A constant representing the tag for schema-name.334*/335private static final int SchemaNameTag = 12;336337/**338* A constant representing the tag for column-precision.339*/340private static final int ColumnPrecisionTag = 13;341342/**343* A constant representing the tag for column-scale.344*/345private static final int ColumnScaleTag = 14;346347/**348* A constant representing the tag for table-name.349*/350private static final int MetaTableNameTag = 15;351352/**353* A constant representing the tag for catalog-name.354*/355private static final int CatalogNameTag = 16;356357/**358* A constant representing the tag for column-type.359*/360private static final int ColumnTypeTag = 17;361362/**363* A constant representing the tag for column-type-name.364*/365private static final int ColumnTypeNameTag = 18;366367/**368* A constant representing the tag for null.369*/370private static final int MetaNullTag = 19;371372private String [] data = {"currentRow", "columnValue", "insertRow", "deleteRow", "insdel", "updateRow", "null" , "emptyString"};373374private static final int RowTag = 0;375private static final int ColTag = 1;376private static final int InsTag = 2;377private static final int DelTag = 3;378private static final int InsDelTag = 4;379private static final int UpdTag = 5;380private static final int NullTag = 6;381private static final int EmptyStringTag = 7;382383/**384* A constant indicating the state of this <code>XmlReaderContentHandler</code>385* object in which it has not yet been called by the SAX parser and therefore386* has no indication of what type of input to expect from the parser next.387* <P>388* The state is set to <code>INITIAL</code> at the end of each389* section, which allows the sections to appear in any order and390* still be parsed correctly (except that metadata must be391* set before data values can be set).392*/393private static final int INITIAL = 0;394395/**396* A constant indicating the state in which this <code>XmlReaderContentHandler</code>397* object expects the next input received from the398* SAX parser to be a string corresponding to one of the elements in399* <code>properties</code>.400*/401private static final int PROPERTIES = 1;402403/**404* A constant indicating the state in which this <code>XmlReaderContentHandler</code>405* object expects the next input received from the406* SAX parser to be a string corresponding to one of the elements in407* <code>colDef</code>.408*/409private static final int METADATA = 2;410411/**412* A constant indicating the state in which this <code>XmlReaderContentHandler</code>413* object expects the next input received from the414* SAX parser to be a string corresponding to one of the elements in415* <code>data</code>.416*/417private static final int DATA = 3;418419private JdbcRowSetResourceBundle resBundle;420421/**422* Constructs a new <code>XmlReaderContentHandler</code> object that will423* assist the SAX parser in reading a <code>WebRowSet</code> object in the424* format of an XML document. In addition to setting some default values,425* this constructor creates three <code>HashMap</code> objects, one for426* properties, one for metadata, and one for data. These hash maps map the427* strings sent by the SAX parser to integer constants so that they can be428* compared more efficiently in <code>switch</code> statements.429*430* @param r the <code>RowSet</code> object in XML format that will be read431*/432public XmlReaderContentHandler(RowSet r) {433// keep the rowset we've been given434rs = (WebRowSetImpl)r;435436// set-up the token maps437initMaps();438439// allocate the collection for the updates440updates = new Vector<>();441442// start out with the empty string443columnValue = "";444propertyValue = "";445metaDataValue = "";446447nullVal = false;448idx = 0;449tempStr = "";450tempUpdate = "";451tempCommand = "";452453try {454resBundle = JdbcRowSetResourceBundle.getJdbcRowSetResourceBundle();455} catch(IOException ioe) {456throw new RuntimeException(ioe);457}458}459460/**461* Creates and initializes three new <code>HashMap</code> objects that map462* the strings returned by the SAX parser to <code>Integer</code>463* objects. The strings returned by the parser will match the strings that464* are array elements in this <code>XmlReaderContentHandler</code> object's465* <code>properties</code>, <code>colDef</code>, or <code>data</code>466* fields. For each array element in these fields, there is a corresponding467* constant defined. It is to these constants that the strings are mapped.468* In the <code>HashMap</code> objects, the string is the key, and the469* integer is the value.470* <P>471* The purpose of the mapping is to make comparisons faster. Because comparing472* numbers is more efficient than comparing strings, the strings returned473* by the parser are mapped to integers, which can then be used in a474* <code>switch</code> statement.475*/476private void initMaps() {477int items, i;478479propMap = new HashMap<>();480items = properties.length;481482for (i=0;i<items;i++) {483propMap.put(properties[i], Integer.valueOf(i));484}485486colDefMap = new HashMap<>();487items = colDef.length;488489for (i=0;i<items;i++) {490colDefMap.put(colDef[i], Integer.valueOf(i));491}492493dataMap = new HashMap<>();494items = data.length;495496for (i=0;i<items;i++) {497dataMap.put(data[i], Integer.valueOf(i));498}499500//Initialize connection map here501typeMap = new HashMap<>();502}503504public void startDocument() throws SAXException {505}506507public void endDocument() throws SAXException {508}509510511/**512* Sets this <code>XmlReaderContentHandler</code> object's <code>tag</code>513* field if the given name is the key for a tag and this object's state514* is not <code>INITIAL</code>. The field is set515* to the constant that corresponds to the given element name.516* If the state is <code>INITIAL</code>, the state is set to the given517* name, which will be one of the sections <code>PROPERTIES</code>,518* <code>METADATA</code>, or <code>DATA</code>. In either case, this519* method puts this document handler in the proper state for calling520* the method <code>endElement</code>.521* <P>522* If the state is <code>DATA</code> and the tag is <code>RowTag</code>,523* <code>DelTag</code>, or <code>InsTag</code>, this method moves the524* rowset's cursor to the insert row and sets this525* <code>XmlReaderContentHandler</code> object's <code>idx</code>526* field to <code>0</code> so that it will be in the proper527* state when the parser calls the method <code>endElement</code>.528*529* @param lName the name of the element; either (1) one of the array530* elements in the fields <code>properties</code>,531* <code>colDef</code>, or <code>data</code> or532* (2) one of the <code>RowSet</code> elements533* <code>"properties"</code>, <code>"metadata"</code>, or534* <code>"data"</code>535* @param attributes <code>org.xml.sax.AttributeList</code> objects that are536* attributes of the named section element; may be <code>null</code>537* if there are no attributes, which is the case for538* <code>WebRowSet</code> objects539* @exception SAXException if a general SAX error occurs540*/541public void startElement(String uri, String lName, String qName, Attributes attributes) throws SAXException {542int tag;543String name = "";544545name = lName;546547switch (getState()) {548case PROPERTIES:549550tempCommand = "";551tag = propMap.get(name);552if (tag == PropNullTag)553setNullValue(true);554else555setTag(tag);556break;557case METADATA:558tag = colDefMap.get(name);559560if (tag == MetaNullTag)561setNullValue(true);562else563setTag(tag);564break;565case DATA:566567/**568* This has been added to clear out the values of the previous read569* so that we should not add up values of data between different tags570*/571tempStr = "";572tempUpdate = "";573if(dataMap.get(name) == null) {574tag = NullTag;575} else if(dataMap.get(name) == EmptyStringTag) {576tag = EmptyStringTag;577} else {578tag = dataMap.get(name);579}580581if (tag == NullTag) {582setNullValue(true);583} else if(tag == EmptyStringTag) {584setEmptyStringValue(true);585} else {586setTag(tag);587588if (tag == RowTag || tag == DelTag || tag == InsTag) {589idx = 0;590try {591rs.moveToInsertRow();592} catch (SQLException ex) {593;594}595}596}597598break;599default:600setState(name);601}602603}604605/**606* Sets the value for the given element if <code>name</code> is one of607* the array elements in the fields <code>properties</code>,608* <code>colDef</code>, or <code>data</code> and this609* <code>XmlReaderContentHandler</code> object's state is not610* <code>INITIAL</code>. If the state is <code>INITIAL</code>,611* this method does nothing.612* <P>613* If the state is <code>METADATA</code> and614* the argument supplied is <code>"metadata"</code>, the rowset's615* metadata is set. If the state is <code>PROPERTIES</code>, the616* appropriate property is set using the given name to determine617* the appropriate value. If the state is <code>DATA</code> and618* the argument supplied is <code>"data"</code>, this method sets619* the state to <code>INITIAL</code> and returns. If the argument620* supplied is one of the elements in the field <code>data</code>,621* this method makes the appropriate changes to the rowset's data.622*623* @param lName the name of the element; either (1) one of the array624* elements in the fields <code>properties</code>,625* <code>colDef</code>, or <code>data</code> or626* (2) one of the <code>RowSet</code> elements627* <code>"properties"</code>, <code>"metadata"</code>, or628* <code>"data"</code>629*630* @exception SAXException if a general SAX error occurs631*/632@SuppressWarnings("fallthrough")633public void endElement(String uri, String lName, String qName) throws SAXException {634int tag;635636String name = "";637name = lName;638639switch (getState()) {640case PROPERTIES:641if (name.equals("properties")) {642state = INITIAL;643break;644}645646try {647tag = propMap.get(name);648switch (tag) {649case KeycolsTag:650if (keyCols != null) {651int i[] = new int[keyCols.size()];652for (int j = 0; j < i.length; j++)653i[j] = Integer.parseInt(keyCols.elementAt(j));654rs.setKeyColumns(i);655}656break;657658case PropClassTag:659//Added the handling for Class tags to take care of maps660//Makes an entry into the map upon end of class tag661try{662typeMap.put(Key_map,sun.reflect.misc.ReflectUtil.forName(Value_map));663664}catch(ClassNotFoundException ex) {665throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errmap").toString(), ex.getMessage()));666}667break;668669case MapTag:670//Added the handling for Map to take set the typeMap671rs.setTypeMap(typeMap);672break;673674default:675break;676}677678if (getNullValue()) {679setPropertyValue(null);680setNullValue(false);681} else {682setPropertyValue(propertyValue);683}684} catch (SQLException ex) {685throw new SAXException(ex.getMessage());686}687688// propertyValue need to be reset to an empty string689propertyValue = "";690setTag(-1);691break;692case METADATA:693if (name.equals("metadata")) {694try {695rs.setMetaData(md);696state = INITIAL;697} catch (SQLException ex) {698throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errmetadata").toString(), ex.getMessage()));699}700} else {701try {702if (getNullValue()) {703setMetaDataValue(null);704setNullValue(false);705} else {706setMetaDataValue(metaDataValue);707}708} catch (SQLException ex) {709throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errmetadata").toString(), ex.getMessage()));710711}712// metaDataValue needs to be reset to an empty string713metaDataValue = "";714}715setTag(-1);716break;717case DATA:718if (name.equals("data")) {719state = INITIAL;720return;721}722723if(dataMap.get(name) == null) {724tag = NullTag;725} else {726tag = dataMap.get(name);727}728switch (tag) {729case ColTag:730try {731idx++;732if (getNullValue()) {733insertValue(null);734setNullValue(false);735} else {736insertValue(tempStr);737}738// columnValue now need to be reset to the empty string739columnValue = "";740} catch (SQLException ex) {741throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsertval").toString(), ex.getMessage()));742}743break;744case RowTag:745try {746rs.insertRow();747rs.moveToCurrentRow();748rs.next();749750// Making this as the original to turn off the751// rowInserted flagging752rs.setOriginalRow();753754applyUpdates();755} catch (SQLException ex) {756throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errconstr").toString(), ex.getMessage()));757}758break;759case DelTag:760try {761rs.insertRow();762rs.moveToCurrentRow();763rs.next();764rs.setOriginalRow();765applyUpdates();766rs.deleteRow();767} catch (SQLException ex) {768throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errdel").toString() , ex.getMessage()));769}770break;771case InsTag:772try {773rs.insertRow();774rs.moveToCurrentRow();775rs.next();776applyUpdates();777} catch (SQLException ex) {778throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsert").toString() , ex.getMessage()));779}780break;781782case InsDelTag:783try {784rs.insertRow();785rs.moveToCurrentRow();786rs.next();787rs.setOriginalRow();788applyUpdates();789} catch (SQLException ex) {790throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errinsdel").toString() , ex.getMessage()));791}792break;793794case UpdTag:795try {796if(getNullValue())797{798insertValue(null);799setNullValue(false);800} else if(getEmptyStringValue()) {801insertValue("");802setEmptyStringValue(false);803} else {804updates.add(upd);805}806} catch(SQLException ex) {807throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errupdate").toString() , ex.getMessage()));808}809break;810811default:812break;813}814default:815break;816}817}818819private void applyUpdates() throws SAXException {820// now handle any updates821if (updates.size() > 0) {822try {823Object upd[];824Iterator<?> i = updates.iterator();825while (i.hasNext()) {826upd = (Object [])i.next();827idx = ((Integer)upd[0]).intValue();828829if(!(lastval.equals(upd[1]))){830insertValue((String)(upd[1]));831}832}833834rs.updateRow();835} catch (SQLException ex) {836throw new SAXException(MessageFormat.format(resBundle.handleGetObject("xmlrch.errupdrow").toString() , ex.getMessage()));837}838updates.removeAllElements();839}840841842}843844/**845* Sets a property, metadata, or data value with the characters in846* the given array of characters, starting with the array element847* indicated by <code>start</code> and continuing for <code>length</code>848* number of characters.849* <P>850* The SAX parser invokes this method and supplies851* the character array, start position, and length parameter values it852* got from parsing the XML document. An application programmer never853* invokes this method directly.854*855* @param ch an array of characters supplied by the SAX parser, all or part of856* which will be used to set a value857* @param start the position in the given array at which to start858* @param length the number of consecutive characters to use859*/860public void characters(char[] ch, int start, int length) throws SAXException {861try {862switch (getState()) {863case PROPERTIES:864propertyValue = new String(ch, start, length);865866/**867* This has been added for handling of special characters. When special868* characters are encountered the characters function gets called for869* each of the characters so we need to append the value got in the870* previous call as it is the same data present between the start and871* the end tag.872**/873tempCommand = tempCommand.concat(propertyValue);874propertyValue = tempCommand;875876// Added the following check for handling of type tags in maps877if(tag == PropTypeTag)878{879Key_map = propertyValue;880}881882// Added the following check for handling of class tags in maps883else if(tag == PropClassTag)884{885Value_map = propertyValue;886}887break;888889case METADATA:890891// The parser will come here after the endElement as there is892// "\n" in the after endTag is printed. This will cause a problem893// when the data between the tags is an empty string so adding894// below condition to take care of that situation.895896if (tag == -1)897{898break;899}900901metaDataValue = new String(ch, start, length);902break;903case DATA:904setDataValue(ch, start, length);905break;906default:907;908}909} catch (SQLException ex) {910throw new SAXException(resBundle.handleGetObject("xmlrch.chars").toString() + ex.getMessage());911}912}913914private void setState(String s) throws SAXException {915if (s.equals("webRowSet")) {916state = INITIAL;917} else if (s.equals("properties")) {918if (state != PROPERTIES)919state = PROPERTIES;920else921state = INITIAL;922} else if (s.equals("metadata")) {923if (state != METADATA)924state = METADATA;925else926state = INITIAL;927} else if (s.equals("data")) {928if (state != DATA)929state = DATA;930else931state = INITIAL;932}933934}935936/**937* Retrieves the current state of this <code>XmlReaderContentHandler</code>938* object's rowset, which is stored in the document handler's939* <code>state</code> field.940*941* @return one of the following constants:942* <code>XmlReaderContentHandler.PROPERTIES</code>943* <code>XmlReaderContentHandler.METADATA</code>944* <code>XmlReaderContentHandler.DATA</code>945* <code>XmlReaderContentHandler.INITIAL</code>946*/947private int getState() {948return state;949}950951private void setTag(int t) {952tag = t;953}954955private int getTag() {956return tag;957}958959private void setNullValue(boolean n) {960nullVal = n;961}962963private boolean getNullValue() {964return nullVal;965}966967private void setEmptyStringValue(boolean e) {968emptyStringVal = e;969}970971private boolean getEmptyStringValue() {972return emptyStringVal;973}974975private String getStringValue(String s) {976return s;977}978979private int getIntegerValue(String s) {980return Integer.parseInt(s);981}982983private boolean getBooleanValue(String s) {984985return Boolean.valueOf(s).booleanValue();986}987988private java.math.BigDecimal getBigDecimalValue(String s) {989return new java.math.BigDecimal(s);990}991992private byte getByteValue(String s) {993return Byte.parseByte(s);994}995996private short getShortValue(String s) {997return Short.parseShort(s);998}9991000private long getLongValue(String s) {1001return Long.parseLong(s);1002}10031004private float getFloatValue(String s) {1005return Float.parseFloat(s);1006}10071008private double getDoubleValue(String s) {1009return Double.parseDouble(s);1010}10111012private byte[] getBinaryValue(String s) {1013return s.getBytes();1014}10151016private java.sql.Date getDateValue(String s) {1017return new java.sql.Date(getLongValue(s));1018}10191020private java.sql.Time getTimeValue(String s) {1021return new java.sql.Time(getLongValue(s));1022}10231024private java.sql.Timestamp getTimestampValue(String s) {1025return new java.sql.Timestamp(getLongValue(s));1026}10271028private void setPropertyValue(String s) throws SQLException {1029// find out if we are going to be dealing with a null1030boolean nullValue = getNullValue();10311032switch(getTag()) {1033case CommandTag:1034if (nullValue)1035; //rs.setCommand(null);1036else1037rs.setCommand(s);1038break;1039case ConcurrencyTag:1040if (nullValue)1041throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());1042else1043rs.setConcurrency(getIntegerValue(s));1044break;1045case DatasourceTag:1046if (nullValue)1047rs.setDataSourceName(null);1048else1049rs.setDataSourceName(s);1050break;1051case EscapeProcessingTag:1052if (nullValue)1053throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());1054else1055rs.setEscapeProcessing(getBooleanValue(s));1056break;1057case FetchDirectionTag:1058if (nullValue)1059throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());1060else1061rs.setFetchDirection(getIntegerValue(s));1062break;1063case FetchSizeTag:1064if (nullValue)1065throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());1066else1067rs.setFetchSize(getIntegerValue(s));1068break;1069case IsolationLevelTag:1070if (nullValue)1071throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());1072else1073rs.setTransactionIsolation(getIntegerValue(s));1074break;1075case KeycolsTag:1076break;1077case PropColumnTag:1078if (keyCols == null)1079keyCols = new Vector<>();1080keyCols.add(s);1081break;1082case MapTag:1083break;1084case MaxFieldSizeTag:1085if (nullValue)1086throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());1087else1088rs.setMaxFieldSize(getIntegerValue(s));1089break;1090case MaxRowsTag:1091if (nullValue)1092throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());1093else1094rs.setMaxRows(getIntegerValue(s));1095break;1096case QueryTimeoutTag:1097if (nullValue)1098throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());1099else1100rs.setQueryTimeout(getIntegerValue(s));1101break;1102case ReadOnlyTag:1103if (nullValue)1104throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());1105else1106rs.setReadOnly(getBooleanValue(s));1107break;1108case RowsetTypeTag:1109if (nullValue) {1110throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());1111} else {1112//rs.setType(getIntegerValue(s));1113String strType = getStringValue(s);1114int iType = 0;11151116if(strType.trim().equals("ResultSet.TYPE_SCROLL_INSENSITIVE")) {1117iType = 1004;1118} else if(strType.trim().equals("ResultSet.TYPE_SCROLL_SENSITIVE")) {1119iType = 1005;1120} else if(strType.trim().equals("ResultSet.TYPE_FORWARD_ONLY")) {1121iType = 1003;1122}1123rs.setType(iType);1124}1125break;1126case ShowDeletedTag:1127if (nullValue)1128throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue").toString());1129else1130rs.setShowDeleted(getBooleanValue(s));1131break;1132case TableNameTag:1133if (nullValue)1134//rs.setTableName(null);1135;1136else1137rs.setTableName(s);1138break;1139case UrlTag:1140if (nullValue)1141rs.setUrl(null);1142else1143rs.setUrl(s);1144break;1145case SyncProviderNameTag:1146if (nullValue) {1147rs.setSyncProvider(null);1148} else {1149String str = s.substring(0,s.indexOf('@')+1);1150rs.setSyncProvider(str);1151}1152break;1153case SyncProviderVendorTag:1154// to be implemented1155break;1156case SyncProviderVersionTag:1157// to be implemented1158break;1159case SyncProviderGradeTag:1160// to be implemented1161break;1162case DataSourceLock:1163// to be implemented1164break;1165default:1166break;1167}11681169}11701171private void setMetaDataValue(String s) throws SQLException {1172// find out if we are going to be dealing with a null1173boolean nullValue = getNullValue();11741175switch (getTag()) {1176case ColumnCountTag:1177md = new RowSetMetaDataImpl();1178idx = 0;11791180if (nullValue) {1181throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());1182} else {1183md.setColumnCount(getIntegerValue(s));1184}1185break;1186case ColumnDefinitionTag:1187break;1188case ColumnIndexTag:1189idx++;1190break;1191case AutoIncrementTag:1192if (nullValue)1193throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());1194else1195md.setAutoIncrement(idx, getBooleanValue(s));1196break;1197case CaseSensitiveTag:1198if (nullValue)1199throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());1200else1201md.setCaseSensitive(idx, getBooleanValue(s));1202break;1203case CurrencyTag:1204if (nullValue)1205throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());1206else1207md.setCurrency(idx, getBooleanValue(s));1208break;1209case NullableTag:1210if (nullValue)1211throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());1212else1213md.setNullable(idx, getIntegerValue(s));1214break;1215case SignedTag:1216if (nullValue)1217throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());1218else1219md.setSigned(idx, getBooleanValue(s));1220break;1221case SearchableTag:1222if (nullValue)1223throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());1224else1225md.setSearchable(idx, getBooleanValue(s));1226break;1227case ColumnDisplaySizeTag:1228if (nullValue)1229throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());1230else1231md.setColumnDisplaySize(idx, getIntegerValue(s));1232break;1233case ColumnLabelTag:1234if (nullValue)1235md.setColumnLabel(idx, null);1236else1237md.setColumnLabel(idx, s);1238break;1239case ColumnNameTag:1240if (nullValue)1241md.setColumnName(idx, null);1242else1243md.setColumnName(idx, s);12441245break;1246case SchemaNameTag:1247if (nullValue) {1248md.setSchemaName(idx, null); }1249else1250md.setSchemaName(idx, s);1251break;1252case ColumnPrecisionTag:1253if (nullValue)1254throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());1255else1256md.setPrecision(idx, getIntegerValue(s));1257break;1258case ColumnScaleTag:1259if (nullValue)1260throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());1261else1262md.setScale(idx, getIntegerValue(s));1263break;1264case MetaTableNameTag:1265if (nullValue)1266md.setTableName(idx, null);1267else1268md.setTableName(idx, s);1269break;1270case CatalogNameTag:1271if (nullValue)1272md.setCatalogName(idx, null);1273else1274md.setCatalogName(idx, s);1275break;1276case ColumnTypeTag:1277if (nullValue)1278throw new SQLException(resBundle.handleGetObject("xmlrch.badvalue1").toString());1279else1280md.setColumnType(idx, getIntegerValue(s));1281break;1282case ColumnTypeNameTag:1283if (nullValue)1284md.setColumnTypeName(idx, null);1285else1286md.setColumnTypeName(idx, s);1287break;1288default:1289//System.out.println("MetaData: Unknown Tag: (" + getTag() + ")");1290break;12911292}1293}12941295private void setDataValue(char[] ch, int start, int len) throws SQLException {1296switch (getTag()) {1297case ColTag:1298columnValue = new String(ch, start, len);1299/**1300* This has been added for handling of special characters. When special1301* characters are encountered the characters function gets called for1302* each of the characters so we need to append the value got in the1303* previous call as it is the same data present between the start and1304* the end tag.1305**/1306tempStr = tempStr.concat(columnValue);1307break;1308case UpdTag:1309upd = new Object[2];13101311/**1312* This has been added for handling of special characters. When special1313* characters are encountered the characters function gets called for1314* each of the characters so we need to append the value got in the1315* previous call as it is the same data present between the start and1316* the end tag.1317**/13181319tempUpdate = tempUpdate.concat(new String(ch,start,len));1320upd[0] = Integer.valueOf(idx);1321upd[1] = tempUpdate;1322//updates.add(upd);13231324lastval = (String)upd[1];1325//insertValue(ch, start, len);1326break;1327case InsTag:13281329}1330}13311332private void insertValue(String s) throws SQLException {13331334if (getNullValue()) {1335rs.updateNull(idx);1336return;1337}13381339// no longer have to deal with those pesky nulls.1340int type = rs.getMetaData().getColumnType(idx);1341switch (type) {1342case java.sql.Types.BIT:1343rs.updateBoolean(idx, getBooleanValue(s));1344break;1345case java.sql.Types.BOOLEAN:1346rs.updateBoolean(idx, getBooleanValue(s));1347break;1348case java.sql.Types.SMALLINT:1349case java.sql.Types.TINYINT:1350rs.updateShort(idx, getShortValue(s));1351break;1352case java.sql.Types.INTEGER:1353rs.updateInt(idx, getIntegerValue(s));1354break;1355case java.sql.Types.BIGINT:1356rs.updateLong(idx, getLongValue(s));1357break;1358case java.sql.Types.REAL:1359case java.sql.Types.FLOAT:1360rs.updateFloat(idx, getFloatValue(s));1361break;1362case java.sql.Types.DOUBLE:1363rs.updateDouble(idx, getDoubleValue(s));1364break;1365case java.sql.Types.NUMERIC:1366case java.sql.Types.DECIMAL:1367rs.updateObject(idx, getBigDecimalValue(s));1368break;1369case java.sql.Types.BINARY:1370case java.sql.Types.VARBINARY:1371case java.sql.Types.LONGVARBINARY:1372rs.updateBytes(idx, getBinaryValue(s));1373break;1374case java.sql.Types.DATE:1375rs.updateDate(idx, getDateValue(s));1376break;1377case java.sql.Types.TIME:1378rs.updateTime(idx, getTimeValue(s));1379break;1380case java.sql.Types.TIMESTAMP:1381rs.updateTimestamp(idx, getTimestampValue(s));1382break;1383case java.sql.Types.CHAR:1384case java.sql.Types.VARCHAR:1385case java.sql.Types.LONGVARCHAR:1386rs.updateString(idx, getStringValue(s));1387break;1388default:13891390}13911392}13931394/**1395* Throws the given <code>SAXParseException</code> object. This1396* exception was originally thrown by the SAX parser and is passed1397* to the method <code>error</code> when the SAX parser invokes it.1398*1399* @param e the <code>SAXParseException</code> object to throw1400*/1401public void error (SAXParseException e) throws SAXParseException {1402throw e;1403}14041405// dump warnings too1406/**1407* Prints a warning message to <code>System.out</code> giving the line1408* number and uri for what caused the warning plus a message explaining1409* the reason for the warning. This method is invoked by the SAX parser.1410*1411* @param err a warning generated by the SAX parser1412*/1413public void warning (SAXParseException err) throws SAXParseException {1414System.out.println (MessageFormat.format(resBundle.handleGetObject("xmlrch.warning").toString(), new Object[] { err.getMessage(), err.getLineNumber(), err.getSystemId() }));1415}14161417/**1418*1419*/1420public void notationDecl(String name, String publicId, String systemId) {14211422}14231424/**1425*1426*/1427public void unparsedEntityDecl(String name, String publicId, String systemId, String notationName) {14281429}14301431/**1432* Returns the current row of this <code>Rowset</code>object.1433* The ResultSet's cursor is positioned at the Row which is needed1434*1435* @return the <code>Row</code> object on which the <code>RowSet</code>1436* implementation objects's cursor is positioned1437*/1438private Row getPresentRow(WebRowSetImpl rs) throws SQLException {1439//rs.setOriginalRow();1440// ResultSetMetaData rsmd = rs.getMetaData();1441// int numCols = rsmd.getColumnCount();1442// Object vals[] = new Object[numCols];1443// for(int j = 1; j<= numCols ; j++){1444// vals[j-1] = rs.getObject(j);1445// }1446// return(new Row(numCols, vals));1447return null;1448}14491450145114521453}145414551456