Source Code Cross Referenced for CachedRowSetXImpl5.java in  » IDE-Netbeans » visualweb.api.designer » com » sun » sql » rowset » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » IDE Netbeans » visualweb.api.designer » com.sun.sql.rowset 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
0003:         *
0004:         * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
0005:         *
0006:         * The contents of this file are subject to the terms of either the GNU
0007:         * General Public License Version 2 only ("GPL") or the Common
0008:         * Development and Distribution License("CDDL") (collectively, the
0009:         * "License"). You may not use this file except in compliance with the
0010:         * License. You can obtain a copy of the License at
0011:         * http://www.netbeans.org/cddl-gplv2.html
0012:         * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
0013:         * specific language governing permissions and limitations under the
0014:         * License.  When distributing the software, include this License Header
0015:         * Notice in each file and include the License file at
0016:         * nbbuild/licenses/CDDL-GPL-2-CP.  Sun designates this
0017:         * particular file as subject to the "Classpath" exception as provided
0018:         * by Sun in the GPL Version 2 section of the License file that
0019:         * accompanied this code. If applicable, add the following below the
0020:         * License Header, with the fields enclosed by brackets [] replaced by
0021:         * your own identifying information:
0022:         * "Portions Copyrighted [year] [name of copyright owner]"
0023:         *
0024:         * Contributor(s):
0025:         *
0026:         * The Original Software is NetBeans. The Initial Developer of the Original
0027:         * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
0028:         * Microsystems, Inc. All Rights Reserved.
0029:         *
0030:         * If you wish your version of this file to be governed by only the CDDL
0031:         * or only the GPL Version 2, indicate your decision by adding
0032:         * "[Contributor] elects to include this software in this distribution
0033:         * under the [CDDL or GPL Version 2] license." If you do not indicate a
0034:         * single choice of license, a recipient has the option to distribute
0035:         * your version of this file under either the CDDL, the GPL Version 2 or
0036:         * to extend the choice of license to its licensees as provided above.
0037:         * However, if you add GPL Version 2 code and therefore, elected the GPL
0038:         * Version 2 license, then the option applies only if the new code is
0039:         * made subject to such option by the copyright holder.
0040:         */
0041:        package com.sun.sql.rowset;
0042:
0043:        import javax.sql.rowset.*;
0044:        import java.sql.*;
0045:        import javax.sql.*;
0046:        import javax.naming.*;
0047:        import java.io.*;
0048:        import java.math.*;
0049:        import java.text.MessageFormat;
0050:        import java.util.*;
0051:
0052:        import java.beans.PropertyChangeListener;
0053:        import java.beans.PropertyChangeSupport;
0054:
0055:        import java.io.Serializable;
0056:
0057:        import java.text.DateFormat;
0058:        import java.text.ParseException;
0059:
0060:        import javax.sql.rowset.serial.SerialArray;
0061:        import javax.sql.rowset.serial.SerialBlob;
0062:        import javax.sql.rowset.serial.SerialClob;
0063:        import javax.sql.rowset.serial.SerialRef;
0064:        import javax.sql.rowset.serial.SerialStruct;
0065:        import javax.sql.rowset.serial.SQLInputImpl;
0066:
0067:        import javax.sql.rowset.spi.SyncFactory;
0068:        import javax.sql.rowset.spi.SyncProvider;
0069:        import javax.sql.rowset.spi.SyncProviderException;
0070:        import javax.sql.rowset.spi.TransactionalWriter;
0071:
0072:        import com.sun.rowset.internal.BaseRow;
0073:        import com.sun.rowset.internal.InsertRow;
0074:        import com.sun.rowset.internal.Row;
0075:
0076:        import com.sun.sql.rowset.internal.CachedRowSetXReader;
0077:        import com.sun.sql.rowset.internal.CachedRowSetXWriter;
0078:
0079:        /**
0080:         * The reference implementation of the <code>CachedRowSetX</code> interface. See the interface
0081:         * definition for full behavior and implementation requirements.
0082:         *
0083:         * Note: This implementation is based on the Sun Microsystems Reference Implemenation of
0084:         * <code>CachedRowSet</code>
0085:         * 
0086:         * All jdbc4.0-specific methods have been split offinto a sub-class CachedRowSetXImpl, to
0087:         * enable usage in both JDK5 and JDK6.  This class, which has been made abstract, is 
0088:         * used in the BeanInfo when running in JDK5.
0089:         */
0090:
0091:        public abstract class CachedRowSetXImpl5 extends BaseRowSetX implements 
0092:                CachedRowSetX, RowSetInternal, Serializable, Cloneable {
0093:
0094:            protected static ResourceBundle rb = ResourceBundle.getBundle(
0095:                    "com.sun.sql.rowset.Bundle", Locale.getDefault()); // NOI18N
0096:
0097:            /**
0098:             * The <code>PropertyChangeSupport</code> object helps in providing
0099:             * support for property change listeners.
0100:             */
0101:            protected PropertyChangeSupport propertyChangeSupport;
0102:
0103:            /**
0104:             * The <code>executed</code> flag tells us whether to throw exceptions
0105:             * when methods are called that require the rowset to have been executed
0106:             */
0107:            private boolean executed;
0108:
0109:            /**
0110:             * The <code>internalUseInstance</code> flag tells to ignore exceptional conditions
0111:             * with regard to the rowset not being executed.  We must do this because this class
0112:             * is also used internally and methods are called that would result in a rowset not
0113:             * executed sqlexception if the user called them.
0114:             */
0115:            protected boolean internalUseInstance;
0116:
0117:            protected void initParams() {
0118:                super .initParams();
0119:                propertyChangeSupport = new PropertyChangeSupport(this );
0120:                insertableColumns = null;
0121:            }
0122:
0123:            /**
0124:             * {@inheritDoc}
0125:             */
0126:            public boolean isExecuted() throws SQLException {
0127:                return executed;
0128:            }
0129:
0130:            void checkExecuted() throws SQLException {
0131:                // Don't throw an exception in the middle of commit or rollback changes
0132:                if (internalUseInstance) {
0133:                    return;
0134:                }
0135:                // make sure we have a resultset (methods such as next()
0136:                // prev(), first(), last(), beforeFirst(), beforeLast(),
0137:                // getString() ,setString(), etc, etc., etc., will throw
0138:                // a NPE if there is not resultset internally because
0139:                // the rowset wasn't executed
0140:                //
0141:                // If the row set metadata has been set, even though we never
0142:                // executed a command, then this is OK too.  This is a cached
0143:                // row set and can be initialized without executing a command.
0144:                if (!isExecuted() && this .rowSetMD == null) {
0145:                    throw new SQLException(rb.getString("EXECUTE_NEVER_CALLED")); //NOI18N
0146:                }
0147:            }
0148:
0149:            /**
0150:             * {@inheritDoc}
0151:             */
0152:            public void setDataSourceName(String dataSourceName)
0153:                    throws SQLException {
0154:                String oldValue = getDataSourceName();
0155:                super .setDataSourceName(dataSourceName);
0156:                release();
0157:                propertyChangeSupport.firePropertyChange("dataSourceName",
0158:                        oldValue, dataSourceName); // NOI18N
0159:            }
0160:
0161:            /**
0162:             * {@inheritDoc}
0163:             */
0164:            public void setUrl(String url) throws SQLException {
0165:                String oldValue = getUrl();
0166:                super .setUrl(url);
0167:                release();
0168:                propertyChangeSupport.firePropertyChange("url", oldValue, url); // NOI18N
0169:            }
0170:
0171:            /**
0172:             * {@inheritDoc}
0173:             */
0174:            public void setUsername(String username) {
0175:                String oldValue = getUsername();
0176:                super .setUsername(username);
0177:                try {
0178:                    release();
0179:                } catch (SQLException e) {
0180:                }
0181:                propertyChangeSupport.firePropertyChange("username", oldValue,
0182:                        username); // NOI18N
0183:            }
0184:
0185:            /**
0186:             * {@inheritDoc}
0187:             */
0188:            public void setPassword(String password) {
0189:                String oldValue = getPassword();
0190:                super .setPassword(password);
0191:                propertyChangeSupport.firePropertyChange("password", oldValue,
0192:                        password); // NOI18N
0193:            }
0194:
0195:            /**
0196:             * {@inheritDoc}
0197:             */
0198:            public void setType(int type) throws SQLException {
0199:                int oldValue = 0;
0200:                try {
0201:                    oldValue = getType();
0202:                } catch (SQLException e) {
0203:                }
0204:                super .setType(type);
0205:                propertyChangeSupport
0206:                        .firePropertyChange("type", oldValue, type); // NOI18N
0207:            }
0208:
0209:            /**
0210:             * {@inheritDoc}
0211:             */
0212:            public void setConcurrency(int concurrency) throws SQLException {
0213:                int oldValue = 0;
0214:                try {
0215:                    oldValue = getConcurrency();
0216:                } catch (SQLException e) {
0217:                }
0218:                super .setConcurrency(concurrency);
0219:                propertyChangeSupport.firePropertyChange("concurrency",
0220:                        oldValue, concurrency); // NOI18N
0221:            }
0222:
0223:            /**
0224:             * {@inheritDoc}
0225:             */
0226:            public void setTransactionIsolation(int transactionIsolation)
0227:                    throws SQLException {
0228:                int oldValue = getTransactionIsolation();
0229:                super .setTransactionIsolation(transactionIsolation);
0230:                propertyChangeSupport.firePropertyChange(
0231:                        "transactionIsolation", oldValue, //NOI18N
0232:                        transactionIsolation); // NOI18N
0233:            }
0234:
0235:            /**
0236:             * {@inheritDoc}
0237:             */
0238:            public void setMaxRows(int maxRows) throws SQLException {
0239:                int oldValue = 0;
0240:                try {
0241:                    oldValue = getMaxRows();
0242:                } catch (SQLException e) {
0243:                }
0244:                super .setMaxRows(maxRows);
0245:                propertyChangeSupport.firePropertyChange("maxRows", oldValue,
0246:                        maxRows); // NOI18N
0247:            }
0248:
0249:            /**
0250:             * {@inheritDoc}
0251:             */
0252:            public void setReadOnly(boolean isReadOnly) {
0253:                if (isReadOnly() != isReadOnly) {
0254:                    boolean oldValue = isReadOnly();
0255:                    super .setReadOnly(isReadOnly);
0256:                    propertyChangeSupport.firePropertyChange("readOnly",
0257:                            oldValue, isReadOnly); // NOI18N
0258:                }
0259:            }
0260:
0261:            //--------------------------------------------------------------------
0262:            // PropertyChangeEvents
0263:            //--------------------------------------------------------------------
0264:
0265:            /**
0266:             * {@inheritDoc}
0267:             */
0268:            public void addPropertyChangeListener(
0269:                    PropertyChangeListener listener) {
0270:                propertyChangeSupport.addPropertyChangeListener(listener);
0271:            }
0272:
0273:            /**
0274:             * {@inheritDoc}
0275:             */
0276:            public void addPropertyChangeListener(String propertyName,
0277:                    PropertyChangeListener listener) {
0278:                propertyChangeSupport.addPropertyChangeListener(propertyName,
0279:                        listener);
0280:            }
0281:
0282:            /**
0283:             * {@inheritDoc}
0284:             * @deprecated
0285:             */
0286:            public void removePropertyChangeListener(
0287:                    PropertyChangeListener listener) {
0288:                propertyChangeSupport.removePropertyChangeListener(listener);
0289:            };
0290:
0291:            /**
0292:             * {@inheritDoc}
0293:             */
0294:            public void removePropertyChangeListener(String propertyName,
0295:                    PropertyChangeListener listener) {
0296:                propertyChangeSupport.removePropertyChangeListener(
0297:                        propertyName, listener);
0298:            }
0299:
0300:            /**
0301:             * The <code>SyncProvider</code> used by the CachedRowSet
0302:             */
0303:            protected SyncProvider provider;
0304:
0305:            /**
0306:             * The <code>RowSetReaderImpl</code> object that is the reader
0307:             * for this rowset.  The method <code>execute</code> uses this
0308:             * reader as part of its implementation.
0309:             * @serial
0310:             */
0311:            protected RowSetReader rowSetReader;
0312:
0313:            /**
0314:             * The <code>RowSetWriterImpl</code> object that is the writer
0315:             * for this rowset.  The method <code>acceptChanges</code> uses
0316:             * this writer as part of its implementation.
0317:             * @serial
0318:             */
0319:            protected RowSetWriter rowSetWriter;
0320:
0321:            /**
0322:             * The <code>Connection</code> object that connects with this
0323:             * <code>CachedRowSetXImpl</code> object's current underlying data source.
0324:             */
0325:            private transient Connection conn;
0326:
0327:            /**
0328:             * The <code>ResultSetMetaData</code> object that contains information
0329:             * about the columns in the <code>ResultSet</code> object that is the
0330:             * current source of data for this <code>CachedRowSetXImpl</code> object.
0331:             */
0332:            private transient ResultSetMetaData rsmd;
0333:
0334:            /**
0335:             * The <code>RowSetMetaData</code> object that contains information about
0336:             * the columns in this <code>CachedRowSetXImpl</code> object.
0337:             * @serial
0338:             */
0339:            protected RowSetMetaData rowSetMD;
0340:
0341:            // Properties of this RowSet
0342:
0343:            /**
0344:             * An array containing the columns in this <code>CachedRowSetXImpl</code>
0345:             * object that form a unique identifier for a row. This array
0346:             * is used by the writer.
0347:             * @serial
0348:             */
0349:            private int keyCols[];
0350:
0351:            /**
0352:             * The name of the table in the underlying database to which updates
0353:             * should be written.  This name is needed because most drivers
0354:             * do not return this information in a <code>ResultSetMetaData</code>
0355:             * object.
0356:             * @serial
0357:             */
0358:            private String tableName;
0359:
0360:            /**
0361:             * A <code>Vector</code> object containing the <code>Row</code>
0362:             * objects that comprise  this <code>CachedRowSetXImpl</code> object.
0363:             * @serial
0364:             */
0365:            protected Vector rvh;
0366:            /**
0367:             * The current postion of the cursor in this <code>CachedRowSetXImpl</code>
0368:             * object.
0369:             * @serial
0370:             */
0371:            protected int cursorPos;
0372:
0373:            /**
0374:             * The current postion of the cursor in this <code>CachedRowSetXImpl</code>
0375:             * object not counting rows that have been deleted, if any.
0376:             * <P>
0377:             * For example, suppose that the cursor is on the last row of a rowset
0378:             * that started with five rows and subsequently had the second and third
0379:             * rows deleted. The <code>absolutePos</code> would be <code>3</code>,
0380:             * whereas the <code>cursorPos</code> would be <code>5</code>.
0381:             * @serial
0382:             */
0383:            private int absolutePos;
0384:
0385:            /**
0386:             * The number of deleted rows currently in this <code>CachedRowSetXImpl</code>
0387:             * object.
0388:             * @serial
0389:             */
0390:            protected int numDeleted;
0391:
0392:            /**
0393:             * The total number of rows currently in this <code>CachedRowSetXImpl</code>
0394:             * object.
0395:             * @serial
0396:             */
0397:            protected int numRows;
0398:
0399:            /**
0400:             * A special row used for constructing a new row. A new
0401:             * row is constructed by using <code>ResultSet.updateXXX</code>
0402:             * methods to insert column values into the insert row.
0403:             * @serial
0404:             */
0405:            private InsertRow insertRow;
0406:
0407:            /**
0408:             * A <code>boolean</code> indicating whether the cursor is
0409:             * currently on the insert row.
0410:             * @serial
0411:             */
0412:            private boolean onInsertRow;
0413:
0414:            /**
0415:             * The field that temporarily holds the last position of the
0416:             * cursor before it moved to the insert row, thus preserving
0417:             * the number of the current row to which the cursor may return.
0418:             * @serial
0419:             */
0420:            private int currentRow;
0421:
0422:            /**
0423:             * A <code>boolean</code> indicating whether the last value
0424:             * returned was an SQL <code>NULL</code>.
0425:             * @serial
0426:             */
0427:            private boolean lastValueNull;
0428:
0429:            /**
0430:             * A <code>SQLWarning</code> which logs on the warnings
0431:             */
0432:            protected SQLWarning sqlwarn;
0433:
0434:            /**
0435:             * Used to track match column for JoinRowSet consumption
0436:             */
0437:            private String strMatchColumn = ""; //NOI18N
0438:
0439:            /**
0440:             * Used to track match column for JoinRowSet consumption
0441:             */
0442:            private int iMatchColumn = -1;
0443:
0444:            /**
0445:             * A <code>RowSetWarning</code> which logs on the warnings
0446:             */
0447:            protected RowSetWarning rowsetWarning;
0448:
0449:            /**
0450:             * The default SyncProvider for the RI CachedRowSetXImpl
0451:             */
0452:            private String DEFAULT_SYNC_PROVIDER = "com.sun.sql.rowset.providers.RIOptimisticProvider"; //NOI18N
0453:
0454:            /**
0455:             * The boolean variable indicating locatorsUpdateValue
0456:             */
0457:            private boolean dbmslocatorsUpdateCopy;
0458:
0459:            /**
0460:             * The <code>ResultSet</code> object that is used to maintain the data when
0461:             * a ResultSet and start position are passed as parameters to the populate function
0462:             */
0463:            private ResultSet resultSet;
0464:
0465:            /**
0466:             * The integer value indicating the end position in the ResultSetwhere the picking
0467:             * up of rows for populating a CachedRowSet object was left off.
0468:             */
0469:            private int endPos;
0470:
0471:            /**
0472:             * The integer value indicating the end position in the ResultSetwhere the picking
0473:             * up of rows for populating a CachedRowSet object was left off.
0474:             */
0475:            private int prevEndPos;
0476:
0477:            /**
0478:             * The integer value indicating the position in the ResultSet, to populate the
0479:             * CachedRowSet object.
0480:             */
0481:            private int startPos;
0482:
0483:            /**
0484:             * The integer value indicating the positon from where the page prior to this
0485:             * was populated.
0486:             */
0487:            private int startPrev;
0488:
0489:            /**
0490:             * The integer value indicating size of the page.
0491:             */
0492:            private int pageSize;
0493:
0494:            /**
0495:             * The integer value indicating number of rows that have been processed so far.
0496:             * Used for checking whether maxRows has been reached or not.
0497:             */
0498:            private int maxRowsreached;
0499:            /**
0500:             * The boolean value when true signifies that pages are still to follow and a
0501:             * false value indicates that this is the last page.
0502:             */
0503:            private boolean pagenotend = true;
0504:
0505:            /**
0506:             * The boolean value indicating whether this is the first page or not.
0507:             */
0508:            private boolean onFirstPage;
0509:
0510:            /**
0511:             * The boolean value indicating whether this is the last page or not.
0512:             */
0513:            private boolean onLastPage;
0514:
0515:            /**
0516:             * The integer value indicating how many times the populate function has been called.
0517:             */
0518:            private int populatecallcount;
0519:
0520:            /**
0521:             * The integer value indicating the total number of rows to be processed in the
0522:             * ResultSet object passed to the populate function.
0523:             */
0524:            private int totalRows;
0525:
0526:            /**
0527:             * The boolean value indicating how the CahedRowSet object has been populated for
0528:             * paging purpose. True indicates that connection parameter is passed.
0529:             */
0530:            private boolean callWithCon;
0531:
0532:            /**
0533:             * CachedRowSet reader object to read the data from the ResultSet when a connection
0534:             * parameter is passed to populate the CachedRowSet object for paging.
0535:             */
0536:            private CachedRowSetXReader crsReader;
0537:
0538:            /**
0539:             * The Vector holding the Match Columns
0540:             */
0541:            private Vector iMatchColumns;
0542:
0543:            /**
0544:             * The Vector that will hold the Match Column names.
0545:             */
0546:            private Vector strMatchColumns;
0547:
0548:            /**
0549:             * Trigger that indicates whether the active SyncProvider is exposes the
0550:             * additional TransactionalWriter method
0551:             */
0552:            private boolean tXWriter = false;
0553:
0554:            /**
0555:             * The field object for a transactional RowSet writer
0556:             */
0557:            private TransactionalWriter tWriter = null;
0558:
0559:            /**
0560:             * Sets the <code>rvh</code> field to a new <code>Vector</code>
0561:             * object with a capacity of 100 and sets the
0562:             * <code>cursorPos</code> and <code>numRows</code> fields to zero.
0563:             */
0564:            protected void initContainer() {
0565:
0566:                rvh = new Vector(100);
0567:                cursorPos = 0;
0568:                absolutePos = 0;
0569:                numRows = 0;
0570:                numDeleted = 0;
0571:                rsmd = null;
0572:                rowSetMD = null;
0573:            }
0574:
0575:            /**
0576:             * Sets the properties for this <code>CachedRowSetXImpl</code> object to
0577:             * their default values. This method is called internally by the
0578:             * default constructor.
0579:             */
0580:
0581:            protected void initProperties() throws SQLException {
0582:                setShowDeleted(false);
0583:                setQueryTimeout(0);
0584:                setMaxRows(0);
0585:                setMaxFieldSize(0);
0586:                setType(ResultSet.TYPE_SCROLL_INSENSITIVE);
0587:                setConcurrency(ResultSet.CONCUR_UPDATABLE);
0588:                setReadOnly(true);
0589:                setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);
0590:                setEscapeProcessing(true);
0591:                setTypeMap(null);
0592:                checkTransactionalWriter();
0593:
0594:                // insert row setup
0595:                onInsertRow = false;
0596:                insertRow = null;
0597:
0598:                executed = false;
0599:
0600:                //Instantiating the vector for MatchColumns
0601:
0602:                iMatchColumns = new Vector(10);
0603:                for (int i = 0; i < 10; i++) {
0604:                    iMatchColumns.add(i, new Integer(-1));
0605:                }
0606:
0607:                strMatchColumns = new Vector(10);
0608:                for (int j = 0; j < 10; j++) {
0609:                    strMatchColumns.add(j, null);
0610:                }
0611:            }
0612:
0613:            /**
0614:             * Determine whether the SyncProvider's writer implements the
0615:             * <code>TransactionalWriter<code> interface
0616:             */
0617:            private void checkTransactionalWriter() {
0618:                if (rowSetWriter != null) {
0619:                    Class c = rowSetWriter.getClass();
0620:                    if (c != null) {
0621:                        Class[] theInterfaces = c.getInterfaces();
0622:                        for (int i = 0; i < theInterfaces.length; i++) {
0623:                            if ((theInterfaces[i].getName())
0624:                                    .indexOf("TransactionalWriter") > 0) { //NOI18N
0625:                                tXWriter = true;
0626:                                establishTransactionalWriter();
0627:                            }
0628:                        }
0629:                    }
0630:                }
0631:            }
0632:
0633:            /**
0634:             * Sets an private field to all transaction bounddaries to be set
0635:             */
0636:            private void establishTransactionalWriter() {
0637:                tWriter = (TransactionalWriter) provider.getRowSetWriter();
0638:            }
0639:
0640:            //-----------------------------------------------------------------------
0641:            // Properties
0642:            //-----------------------------------------------------------------------
0643:
0644:            /**
0645:             * {@inheritDoc}
0646:             */
0647:            public void setCommand(String command) throws SQLException {
0648:
0649:                String oldValue = getCommand();
0650:                super .setCommand(command);
0651:                release();
0652:                propertyChangeSupport.firePropertyChange("command", oldValue,
0653:                        command); // NOI18N
0654:            }
0655:
0656:            //---------------------------------------------------------------------
0657:            // Reading and writing data
0658:            //---------------------------------------------------------------------
0659:
0660:            /**
0661:             * {@inheritDoc}
0662:             */
0663:            public void populate(ResultSet data) throws SQLException {
0664:                int rowsFetched;
0665:                Row currentRow;
0666:                int numCols;
0667:                int i;
0668:                Map map = getTypeMap();
0669:                Object obj;
0670:                int mRows;
0671:
0672:                if (data == null) {
0673:                    throw new SQLException(rb
0674:                            .getString("INVALID_RESULTSET_SUPPLIED")); //NOI18N
0675:                }
0676:
0677:                // get the meta data for this ResultSet
0678:                rsmd = data.getMetaData();
0679:
0680:                // set up the metadata
0681:                rowSetMD = new RowSetMetaDataXImpl();
0682:                initMetaData(rowSetMD, rsmd);
0683:
0684:                // release the meta-data so that aren't tempted to use it.
0685:                rsmd = null;
0686:                numCols = rowSetMD.getColumnCount();
0687:                mRows = this .getMaxRows();
0688:                rowsFetched = 0;
0689:                currentRow = null;
0690:
0691:                while (data.next()) {
0692:
0693:                    currentRow = new Row(numCols);
0694:
0695:                    if (rowsFetched > mRows && mRows > 0) {
0696:                        rowsetWarning.setNextWarning(new RowSetWarning(rb
0697:                                .getString("MAX_ROWS_EXCEEDED"))); //NOI18N
0698:                    }
0699:
0700:                    for (i = 1; i <= numCols; i++) {
0701:                        /*
0702:                         * check if the user has set a map. If no map
0703:                         * is set then use plain getObject. This lets
0704:                         * us work with drivers that do not support
0705:                         * getObject with a map in fairly sensible way
0706:                         */
0707:                        if (map == null) {
0708:                            obj = data.getObject(i);
0709:                        } else {
0710:                            obj = data.getObject(i, map);
0711:                        }
0712:                        /*
0713:                         * the following block checks for the various
0714:                         * types that we have to serialize in order to
0715:                         * store - right now only structs have been tested
0716:                         */
0717:                        if (obj instanceof  Struct) {
0718:                            obj = new SerialStruct((Struct) obj, map);
0719:                        } else if (obj instanceof  SQLData) {
0720:                            obj = new SerialStruct((SQLData) obj, map);
0721:                        } else if (obj instanceof  Blob) {
0722:                            obj = new SerialBlob((Blob) obj);
0723:                        } else if (obj instanceof  Clob) {
0724:                            obj = new SerialClob((Clob) obj);
0725:                        } else if (obj instanceof  java.sql.Array) {
0726:                            obj = new SerialArray((java.sql.Array) obj, map);
0727:                        }
0728:
0729:                        ((Row) currentRow).initColumnObject(i, obj);
0730:                    }
0731:                    rowsFetched++;
0732:                    rvh.add(currentRow);
0733:                }
0734:                executed = true;
0735:
0736:                numRows = rowsFetched;
0737:                // Also rowsFetched should be equal to rvh.size()
0738:
0739:                // notify any listeners that the rowset has changed
0740:                notifyRowSetChanged();
0741:            }
0742:
0743:            /**
0744:             * Initializes the given <code>RowSetMetaData</code> object with the values
0745:             * in the given <code>ResultSetMetaData</code> object.
0746:             *
0747:             * @param md the <code>RowSetMetaData</code> object for this
0748:             *           <code>CachedRowSetXImpl</code> object, which will be set with
0749:             *           values from rsmd
0750:             * @param rsmd the <code>ResultSetMetaData</code> object from which new
0751:             *             values for md will be read
0752:             * @throws SQLException if an error occurs
0753:             */
0754:            private void initMetaData(RowSetMetaData md, ResultSetMetaData rsmd)
0755:                    throws SQLException {
0756:
0757:                RowSetMetaDataX mdx = null;
0758:                if (md instanceof  RowSetMetaDataX) {
0759:                    mdx = (RowSetMetaDataX) md;
0760:                }
0761:
0762:                Log.getLogger()
0763:                        .entering(getClass().getName(), "initMetaData()");
0764:                int numCols = rsmd.getColumnCount();
0765:
0766:                md.setColumnCount(numCols);
0767:                for (int col = 1; col <= numCols; col++) {
0768:                    md.setAutoIncrement(col, rsmd.isAutoIncrement(col));
0769:                    md.setCaseSensitive(col, rsmd.isCaseSensitive(col));
0770:                    md.setCurrency(col, rsmd.isCurrency(col));
0771:                    md.setNullable(col, rsmd.isNullable(col));
0772:                    md.setSigned(col, rsmd.isSigned(col));
0773:                    md.setSearchable(col, rsmd.isSearchable(col));
0774:
0775:                    /*
0776:                     * The PostgreSQL drivers sometimes return negative columnDisplaySize,
0777:                     * which causes an exception to be thrown.  Check for it.
0778:                     */
0779:                    int size = rsmd.getColumnDisplaySize(col);
0780:                    if (size < 0) {
0781:                        size = 0;
0782:                    }
0783:                    md.setColumnDisplaySize(col, size);
0784:
0785:                    md.setColumnLabel(col, rsmd.getColumnLabel(col));
0786:                    md.setColumnName(col, rsmd.getColumnName(col));
0787:                    md.setSchemaName(col, rsmd.getSchemaName(col));
0788:
0789:                    /*
0790:                     * Drivers return some strange values for precision, for non-numeric data, including reports of
0791:                     * non-integer values; maybe we should check type, & set to 0 for non-numeric types.
0792:                     */
0793:                    int precision = rsmd.getPrecision(col);
0794:                    if (precision < 0) {
0795:                        precision = 0;
0796:                    }
0797:                    md.setPrecision(col, precision);
0798:
0799:                    /*
0800:                     * It seems, from a bug report, that a driver can sometimes return a negative
0801:                     * value for scale.  javax.sql.rowset.RowSetMetaDataImpl will throw an exception
0802:                     * if we attempt to set a negative value.  As such, we'll check for this case.
0803:                     */
0804:                    int scale = rsmd.getScale(col);
0805:                    if (scale < 0) {
0806:                        scale = 0;
0807:                    }
0808:                    md.setScale(col, scale);
0809:
0810:                    md.setTableName(col, rsmd.getTableName(col));
0811:                    md.setCatalogName(col, rsmd.getCatalogName(col));
0812:                    md.setColumnType(col, rsmd.getColumnType(col));
0813:                    md.setColumnTypeName(col, rsmd.getColumnTypeName(col));
0814:
0815:                    if (mdx != null) {
0816:                        mdx.setColumnClassName(col, rsmd
0817:                                .getColumnClassName(col));
0818:                        /*
0819:                         * We face a dilemna here.  The RI always says columns are writable.
0820:                         * We'd like to give a better answer; but since we allow joins that
0821:                         * would result in the database saying all columns are readonly, we
0822:                         * can't just hand back the information the driver gives about the
0823:                         * resultset.  As such, we would really like to compute if the column is
0824:                         * writable in much the same way that CachedRowSetXWriter computes this
0825:                         * information.  For now, we'll return true unless the user has provided
0826:                         * information otherwise in the updatable columns on the rowset.
0827:                         *
0828:                         * Actually, even this will cause problems as there is a difference between
0829:                         * insertable and updatable.  We want to allow new rows to specify insertable
0830:                         * columns that are not updatable.  So we will actually honor insertable if it
0831:                         * is present.  If not, we'll use updatable if present.  If not, we'll say the
0832:                         * column is writable.
0833:                         */
0834:                        if (insertableColumns != null
0835:                                && insertableColumns.length >= col) {
0836:                            mdx.setWritable(col, insertableColumns[col - 1]);
0837:                            mdx.setDefinitelyWritable(col,
0838:                                    insertableColumns[col - 1]);
0839:                            mdx.setReadOnly(col, !insertableColumns[col - 1]);
0840:                        } else if (updatableColumns != null
0841:                                && updatableColumns.length >= col) {
0842:                            mdx.setWritable(col, updatableColumns[col - 1]);
0843:                            mdx.setDefinitelyWritable(col,
0844:                                    updatableColumns[col - 1]);
0845:                            mdx.setReadOnly(col, !updatableColumns[col - 1]);
0846:                        } else {
0847:                            mdx.setWritable(col, true);
0848:                            mdx.setDefinitelyWritable(col, false); // We don't know for sure
0849:                            mdx.setReadOnly(col, false);
0850:                        }
0851:                    }
0852:
0853:                    dbmslocatorsUpdateCopy = false;
0854:                    if (conn != null) {
0855:                        try {
0856:                            dbmslocatorsUpdateCopy = conn.getMetaData()
0857:                                    .locatorsUpdateCopy();
0858:                        } catch (SQLException e) {
0859:                            // It seems, some databases throw an exception here (e.g., Pointbase)
0860:                            // assume false (so updateClob/Blob will not work)
0861:                        }
0862:                    }
0863:                }
0864:            }
0865:
0866:            /**
0867:             * {@inheritDoc}
0868:             */
0869:            public void execute(Connection conn) throws SQLException {
0870:
0871:                Log.getLogger().entering(getClass().getName(), "execute()");
0872:
0873:                // store the connection so the reader can find it.
0874:                setConnection(conn);
0875:
0876:                if (getPageSize() != 0) {
0877:                    crsReader = (CachedRowSetXReader) provider
0878:                            .getRowSetReader();
0879:                    crsReader.setStartPosition(1);
0880:                    callWithCon = true;
0881:                    crsReader.readData((RowSetInternal) this );
0882:                }
0883:
0884:                // Now call the current reader's readData method
0885:                else {
0886:                    rowSetReader.readData((RowSetInternal) this );
0887:                }
0888:
0889:                executed = true;
0890:
0891:                rowSetMD = (RowSetMetaDataXImpl) this .getMetaData();
0892:
0893:                if (conn != null) {
0894:                    try {
0895:                        dbmslocatorsUpdateCopy = conn.getMetaData()
0896:                                .locatorsUpdateCopy();
0897:                    } catch (SQLException e) {
0898:                        // It seems, some databases throw an exception here (e.g., Pointbase)
0899:                        // assume false (so updateClob/Blob will not work)
0900:                        dbmslocatorsUpdateCopy = false;
0901:                    }
0902:                } else {
0903:                    Connection tempConn = null;
0904:                    try {
0905:                        tempConn = getConnection(getDataSourceName(), getUrl(),
0906:                                getUsername(), getPassword());
0907:                        dbmslocatorsUpdateCopy = tempConn.getMetaData()
0908:                                .locatorsUpdateCopy();
0909:                    } catch (SQLException e) {
0910:                        // It seems, some databases throw an exception here (e.g., Pointbase)
0911:                        // assume false (so updateClob/Blob will not work)
0912:                        dbmslocatorsUpdateCopy = false;
0913:                    } catch (AbstractMethodError e) {
0914:                        // Some drivers (e.g., Oracle 9) don't implement the locatorsUpdateCopy() method.
0915:                        // Assume false (so updateClob/Blob will not work)
0916:                        dbmslocatorsUpdateCopy = false;
0917:                    } finally {
0918:                        if (tempConn != null) {
0919:                            try {
0920:                                if (!tempConn.getAutoCommit()) {
0921:                                    tempConn.rollback();
0922:                                }
0923:                            } catch (Exception dummy) {
0924:                                /*
0925:                                 * not an error condition, we're closing anyway, but
0926:                                 * we'd like to clean up any locks if we can since
0927:                                 * it is not clear the connection pool will clean
0928:                                 * these connections in a timely manner
0929:                                 */
0930:                            }
0931:                            tempConn.close();
0932:                        }
0933:                    }
0934:                }
0935:            }
0936:
0937:            /**
0938:             * Sets this <code>CachedRowSetXImpl</code> object's connection property
0939:             * to the given <code>Connection</code> object.  This method is called
0940:             * internally by the version of the method <code>execute</code> that takes a
0941:             * <code>Connection</code> object as an argument. The reader for this
0942:             * <code>CachedRowSetXImpl</code> object can retrieve the connection stored
0943:             * in the rowset's connection property by calling its
0944:             * <code>getConnection</code> method.
0945:             *
0946:             * @param connection the <code>Connection</code> object that was passed in
0947:             *                   to the method <code>execute</code> and is to be stored
0948:             *                   in this <code>CachedRowSetXImpl</code> object's connection
0949:             *                   property
0950:             */
0951:            private void setConnection(Connection connection) {
0952:                conn = connection;
0953:            }
0954:
0955:            /**
0956:             * {@inheritDoc}
0957:             */
0958:            public void acceptChanges() throws SyncProviderException {
0959:                try {
0960:                    checkExecuted();
0961:                } catch (SQLException e) {
0962:                    throw new SyncProviderException(e.getMessage());
0963:                }
0964:                if (onInsertRow == true) {
0965:                    throw new SyncProviderException(rb
0966:                            .getString("INVALID_INSERT_ROW_OP")); //NOI18N
0967:                }
0968:
0969:                int saveCursorPos = cursorPos;
0970:                boolean success = false;
0971:                boolean conflict = false;
0972:
0973:                try {
0974:                    if (rowSetWriter != null) {
0975:                        saveCursorPos = cursorPos;
0976:                        conflict = rowSetWriter
0977:                                .writeData((RowSetInternal) this );
0978:                        cursorPos = saveCursorPos;
0979:                    }
0980:
0981:                    if ((tXWriter) && this .COMMIT_ON_ACCEPT_CHANGES) {
0982:                        // do commit/rollback's here
0983:                        if (!conflict) {
0984:                            tWriter = (TransactionalWriter) rowSetWriter;
0985:                            tWriter.rollback();
0986:                            success = false;
0987:                        } else {
0988:                            tWriter = (TransactionalWriter) rowSetWriter;
0989:                            tWriter.commit();
0990:                            success = true;
0991:                        }
0992:                    }
0993:
0994:                    if (success == true) {
0995:                        setOriginal();
0996:                    } else if (!(success) && !(this .COMMIT_ON_ACCEPT_CHANGES)) {
0997:                        throw new SyncProviderException(rb
0998:                                .getString("ACCEPT_CHANGES_FAILED")); //NOI18N
0999:                    }
1000:
1001:                } catch (SyncProviderException spe) {
1002:                    throw spe;
1003:                } catch (SQLException e) {
1004:                    e.printStackTrace();
1005:                    throw new SyncProviderException(e.getMessage());
1006:                } catch (SecurityException e) {
1007:                    throw new SyncProviderException(e.getMessage());
1008:                } finally {
1009:                    try {
1010:                        if (tWriter instanceof  CachedRowSetXWriter) {
1011:                            ((CachedRowSetXWriter) tWriter).closeConnection();
1012:                        }
1013:                    } catch (SQLException e) {
1014:                        // well, we tried
1015:                    }
1016:                }
1017:            }
1018:
1019:            /**
1020:             * {@inheritDoc}
1021:             */
1022:            public void acceptChanges(Connection con)
1023:                    throws SyncProviderException {
1024:
1025:                try {
1026:                    checkExecuted();
1027:                    setConnection(con);
1028:                    acceptChanges();
1029:                } catch (SyncProviderException spe) {
1030:                    throw spe;
1031:                } catch (SQLException sqle) {
1032:                    throw new SyncProviderException(sqle.getMessage());
1033:                }
1034:            }
1035:
1036:            /**
1037:             * {@inheritDoc}
1038:             */
1039:            public void restoreOriginal() throws SQLException {
1040:                checkExecuted();
1041:                Row currentRow;
1042:                for (Iterator i = rvh.iterator(); i.hasNext();) {
1043:                    currentRow = (Row) i.next();
1044:                    if (currentRow.getInserted() == true) {
1045:                        i.remove();
1046:                        --numRows;
1047:                    } else {
1048:                        if (currentRow.getDeleted() == true) {
1049:                            currentRow.clearDeleted();
1050:                            //!JK shouldn't we be doing a ++numRows here?
1051:                        }
1052:                        if (currentRow.getUpdated() == true) {
1053:                            currentRow.clearUpdated();
1054:                        }
1055:                    }
1056:                }
1057:                // move to before the first
1058:                cursorPos = 0;
1059:                absolutePos = 0; //!JK: added this
1060:
1061:                // notify any listeners
1062:                notifyRowSetChanged();
1063:            }
1064:
1065:            /**
1066:             * {@inheritDoc}
1067:             */
1068:            public void release() throws SQLException {
1069:                initContainer();
1070:                executed = false;
1071:                notifyRowSetChanged();
1072:            }
1073:
1074:            /**
1075:             * {@inheritDoc}
1076:             */
1077:            public void undoDelete() throws SQLException {
1078:                checkExecuted();
1079:                if (getShowDeleted() == false) {
1080:                    return;
1081:                }
1082:                // make sure we are on a row
1083:                checkCursor();
1084:
1085:                // don't want this to happen...
1086:                if (onInsertRow == true) {
1087:                    throw new SQLException(rb.getString("INVALID_CURSOR_POS")); //NOI18N
1088:                }
1089:
1090:                Row currentRow = (Row) getCurrentRow();
1091:                if (currentRow.getDeleted() == true) {
1092:                    currentRow.clearDeleted();
1093:                    --numDeleted;
1094:                    notifyRowChanged();
1095:                }
1096:            }
1097:
1098:            /**
1099:             * {@inheritDoc}
1100:             */
1101:            public void undoInsert() throws SQLException {
1102:                checkExecuted();
1103:                // make sure we are on a row
1104:                checkCursor();
1105:
1106:                // don't want this to happen...
1107:                if (onInsertRow == true) {
1108:                    throw new SQLException(rb.getString("INVALID_CURSOR_POS")); //NOI18N
1109:                }
1110:
1111:                Row currentRow = (Row) getCurrentRow();
1112:                if (currentRow.getInserted() == true) {
1113:                    rvh.remove(cursorPos);
1114:                    --numRows;
1115:                    notifyRowChanged();
1116:                } else {
1117:                    throw new SQLException(rb
1118:                            .getString("INVALID_INSERT_ROW_OP")); //NOI18N
1119:                }
1120:            }
1121:
1122:            /**
1123:             * {@inheritDoc}
1124:             */
1125:            public void undoUpdate() throws SQLException {
1126:                checkExecuted();
1127:                // if on insert row, cancel the insert row
1128:                // make the insert row flag,
1129:                // cursorPos back to the current row
1130:                moveToCurrentRow();
1131:
1132:                // else if not on insert row
1133:                // call undoUpdate or undoInsert
1134:                undoDelete();
1135:
1136:                undoInsert();
1137:
1138:            }
1139:
1140:            //--------------------------------------------------------------------
1141:            // Views
1142:            //--------------------------------------------------------------------
1143:
1144:            /**
1145:             * {@inheritDoc}
1146:             */
1147:            public RowSet createShared() throws SQLException {
1148:                checkExecuted(); //!JK ?
1149:                RowSet clone;
1150:                try {
1151:                    clone = (RowSet) clone();
1152:                } catch (CloneNotSupportedException ex) {
1153:                    throw new SQLException(ex.getMessage());
1154:                }
1155:                return clone;
1156:            }
1157:
1158:            /**
1159:             * Returns a new <code>RowSet</code> object containing by the same data
1160:             * as this <code>CachedRowSetXImpl</code> object.  This method
1161:             * differs from the method <code>createCopy</code> in that it throws a
1162:             * <code>CloneNotSupportedException</code> object instead of an
1163:             * <code>SQLException</code> object, as the method <code>createShared</code>
1164:             * does.  This <code>clone</code>
1165:             * method is called internally by the method <code>createShared</code>,
1166:             * which catches the <code>CloneNotSupportedException</code> object
1167:             * and in turn throws a new <code>SQLException</code> object.
1168:             *
1169:             * @return a copy of this <code>CachedRowSetXImpl</code> object
1170:             * @throws CloneNotSupportedException if an error occurs when
1171:             * attempting to clone this <code>CachedRowSetXImpl</code> object
1172:             * @see #createShared
1173:             */
1174:            protected Object clone() throws CloneNotSupportedException {
1175:                return (super .clone());
1176:            }
1177:
1178:            /**
1179:             * {@inheritDoc}
1180:             */
1181:            public CachedRowSet createCopy() throws SQLException {
1182:                checkExecuted(); //!JK ?
1183:                ObjectOutputStream out;
1184:                ByteArrayOutputStream bOut = new ByteArrayOutputStream();
1185:                try {
1186:                    out = new ObjectOutputStream(bOut);
1187:                    out.writeObject(this );
1188:                } catch (IOException ex) {
1189:                    throw new SQLException(rb.getString("CLONE_FAILED"
1190:                            + ex.getMessage())); //NOI18N
1191:                }
1192:
1193:                ObjectInputStream in;
1194:
1195:                try {
1196:                    ByteArrayInputStream bIn = new ByteArrayInputStream(bOut
1197:                            .toByteArray());
1198:                    in = new ObjectInputStream(bIn);
1199:                } catch (StreamCorruptedException ex) {
1200:                    throw new SQLException(rb.getString("CLONE_FAILED"
1201:                            + ex.getMessage())); //NOI18N
1202:                } catch (IOException ex) {
1203:                    throw new SQLException(rb.getString("CLONE_FAILED"
1204:                            + ex.getMessage())); //NOI18N
1205:                }
1206:
1207:                try {
1208:                    return ((CachedRowSet) (in.readObject()));
1209:                } catch (ClassNotFoundException ex) {
1210:                    throw new SQLException(rb.getString("CLONE_FAILED"
1211:                            + ex.getMessage())); //NOI18N
1212:                } catch (OptionalDataException ex) {
1213:                    throw new SQLException(rb.getString("CLONE_FAILED"
1214:                            + ex.getMessage())); //NOI18N
1215:                } catch (IOException ex) {
1216:                    throw new SQLException(rb.getString("CLONE_FAILED"
1217:                            + ex.getMessage())); //NOI18N
1218:                }
1219:            }
1220:
1221:            /**
1222:             * {@inheritDoc}
1223:             */
1224:            public CachedRowSet createCopySchema() throws SQLException {
1225:                checkExecuted(); //!JK ?
1226:                // Copy everything except data i.e all constraints
1227:
1228:                // Store the number of rows of "this"
1229:                // and make numRows equals zero.
1230:                // and make data also zero.
1231:                int nRows = numRows;
1232:                numRows = 0;
1233:
1234:                CachedRowSet crs = this .createCopy();
1235:
1236:                // reset this object back to number of rows.
1237:                numRows = nRows;
1238:
1239:                return crs;
1240:            }
1241:
1242:            /**
1243:             * {@inheritDoc}
1244:             */
1245:            public CachedRowSet createCopyNoConstraints() throws SQLException {
1246:                checkExecuted(); //!JK ?
1247:                // Copy the whole data ONLY without any constraints.
1248:                CachedRowSetXImpl5 crs;
1249:                crs = (CachedRowSetXImpl5) this .createCopy();
1250:
1251:                crs.initProperties();
1252:                try {
1253:                    crs.unsetMatchColumn(crs.getMatchColumnIndexes());
1254:                } catch (SQLException sqle) {
1255:                    //do nothing, if the setMatchColumn is not set.
1256:                }
1257:
1258:                try {
1259:                    crs.unsetMatchColumn(crs.getMatchColumnNames());
1260:                } catch (SQLException sqle) {
1261:                    //do nothing, if the setMatchColumn is not set.
1262:                }
1263:
1264:                return crs;
1265:            }
1266:
1267:            /**
1268:             * {@inheritDoc}
1269:             */
1270:            public Collection toCollection() throws SQLException {
1271:                checkExecuted(); //!JK ?
1272:
1273:                TreeMap tMap;
1274:                int count = 0;
1275:                Row origRow;
1276:                Vector newRow;
1277:
1278:                int colCount = rowSetMD.getColumnCount();
1279:                tMap = new TreeMap();
1280:
1281:                for (int i = 0; i < numRows; i++) {
1282:                    tMap.put(new Integer(i), rvh.get(i));
1283:                }
1284:
1285:                return (tMap.values());
1286:            }
1287:
1288:            /**
1289:             * {@inheritDoc}
1290:             */
1291:            public Collection toCollection(int column) throws SQLException {
1292:                checkExecuted(); //!JK ?
1293:
1294:                Vector vec;
1295:                Row origRow;
1296:                int nRows = numRows;
1297:                vec = new Vector(nRows);
1298:
1299:                // create a copy
1300:                CachedRowSetXImpl5 crsTemp;
1301:                crsTemp = (CachedRowSetXImpl5) this .createCopy();
1302:
1303:                while (nRows != 0) {
1304:                    crsTemp.next();
1305:                    vec.add(crsTemp.getObject(column));
1306:                    nRows--;
1307:                }
1308:
1309:                return (Collection) vec;
1310:            }
1311:
1312:            /**
1313:             * {@inheritDoc}
1314:             */
1315:            public Collection toCollection(String column) throws SQLException {
1316:                checkExecuted(); //!JK ?
1317:                return toCollection(getColIdxByName(column));
1318:            }
1319:
1320:            //--------------------------------------------------------------------
1321:            // Advanced features
1322:            //--------------------------------------------------------------------
1323:
1324:            /**
1325:             * {@inheritDoc}
1326:             */
1327:            public SyncProvider getSyncProvider() throws SQLException {
1328:                return provider;
1329:            }
1330:
1331:            /**
1332:             * {@inheritDoc}
1333:             */
1334:            public void setSyncProvider(String providerStr) throws SQLException {
1335:                provider = (SyncProvider) SyncFactory.getInstance(providerStr);
1336:
1337:                rowSetReader = provider.getRowSetReader();
1338:                rowSetWriter = (TransactionalWriter) provider.getRowSetWriter();
1339:            }
1340:
1341:            //-----------------
1342:            // methods inherited from RowSet
1343:            //-----------------
1344:
1345:            //---------------------------------------------------------------------
1346:            // Reading and writing data
1347:            //---------------------------------------------------------------------
1348:
1349:            /**
1350:             * {@inheritDoc}
1351:             */
1352:            public void execute() throws SQLException {
1353:                execute(null);
1354:            }
1355:
1356:            //-----------------------------------
1357:            // Methods inherited from ResultSet
1358:            //-----------------------------------
1359:
1360:            /**
1361:             * {@inheritDoc}
1362:             */
1363:            public boolean next() throws SQLException {
1364:                checkExecuted();
1365:                /*
1366:                 * make sure things look sane. The cursor must be
1367:                 * positioned in the rowset or before first (0) or
1368:                 * after last (numRows + 1)
1369:                 */
1370:                if (cursorPos < 0 || cursorPos >= numRows + 1) {
1371:                    throw new SQLException(rb.getString("INVALID_CURSOR_POS")); //NOI18N
1372:                }
1373:                // now move and notify
1374:                boolean ret = this .internalNext();
1375:                notifyCursorMoved();
1376:
1377:                return ret;
1378:            }
1379:
1380:            /**
1381:             * Moves this <code>CachedRowSetXImpl</code> object's cursor to the next
1382:             * row and returns <code>true</code> if the cursor is still in the rowset;
1383:             * returns <code>false</code> if the cursor has moved to the position after
1384:             * the last row.
1385:             * <P>
1386:             * This method handles the cases where the cursor moves to a row that
1387:             * has been deleted.
1388:             * If this rowset shows deleted rows and the cursor moves to a row
1389:             * that has been deleted, this method moves the cursor to the next
1390:             * row until the cursor is on a row that has not been deleted.
1391:             * <P>
1392:             * The method <code>internalNext</code> is called by methods such as
1393:             * <code>next</code>, <code>absolute</code>, and <code>relative</code>,
1394:             * and, as its name implies, is only called internally.
1395:             * <p>
1396:             * This is a implementation only method and is not required as a standard
1397:             * implementation of the <code>CachedRowSet</code> interface.
1398:             *
1399:             * @return <code>true</code> if the cursor is on a valid row in this
1400:             *         rowset; <code>false</code> if it is after the last row
1401:             * @throws SQLException if an error occurs
1402:             */
1403:            protected boolean internalNext() throws SQLException {
1404:                boolean ret = false;
1405:                //System.out.println("internalNext(): start");
1406:
1407:                do {
1408:                    //System.out.println("internalNext(): do top: cursorPos: " + cursorPos + ", numRows: " + numRows);
1409:                    if (cursorPos < numRows) {
1410:                        ++cursorPos;
1411:                        ret = true;
1412:                        //System.out.println("internalNext(): do: case was cursorPos < numRows: cursorPos: " + cursorPos + ", ret: " + ret);
1413:                    } else if (cursorPos == numRows) {
1414:                        // increment to after last
1415:                        ++cursorPos;
1416:                        ret = false;
1417:                        //System.out.println("internalNext(): do: case was cursorPos == numRows: cursorPos: " + cursorPos + ", ret: " + ret);
1418:                        break;
1419:                    }
1420:                } while ((getShowDeleted() == false) && (rowDeleted() == true));
1421:                //System.out.println("internalNext(): fell through the while");
1422:
1423:                /* each call to internalNext may increment cursorPos multiple
1424:                 * times however, the absolutePos only increments once per call.
1425:                 */
1426:                if (ret == true)
1427:                    absolutePos++;
1428:                else
1429:                    absolutePos = 0;
1430:
1431:                //System.out.println("internalNext(): returning: cursorPos: " + cursorPos + ", absolutePos: " + absolutePos + ", numRows: " + numRows + ", ret: " + ret);
1432:                return ret;
1433:            }
1434:
1435:            /**
1436:             * {@inheritDoc}
1437:             */
1438:            public void close() {
1439:
1440:                // close all data structures holding
1441:                // the disconnected rowset
1442:
1443:                cursorPos = 0;
1444:                absolutePos = 0;
1445:                numRows = 0;
1446:                numDeleted = 0;
1447:
1448:                // set all insert(s), update(s) & delete(s),
1449:                // if at all, to their initial values.
1450:                try {
1451:                    initProperties();
1452:                } catch (SQLException e) {
1453:                }
1454:
1455:                // clear the vector of it's present contents
1456:                rvh.clear();
1457:
1458:                // this will make it eligible for gc
1459:                // rvh = null;
1460:            }
1461:
1462:            /**
1463:             * {@inheritDoc}
1464:             */
1465:            public boolean wasNull() throws SQLException {
1466:                checkExecuted();
1467:                return lastValueNull;
1468:            }
1469:
1470:            /**
1471:             * Sets the field <code>lastValueNull</code> to the given
1472:             * <code>boolean</code> value.
1473:             *
1474:             * @param value <code>true</code> to indicate that the value of
1475:             *        the last column read was SQL <code>NULL</code>;
1476:             *        <code>false</code> to indicate that it was not
1477:             */
1478:            private void setLastValueNull(boolean value) {
1479:                lastValueNull = value;
1480:            }
1481:
1482:            //======================================================================
1483:            // Methods for accessing results by column index
1484:            //======================================================================
1485:
1486:            /**
1487:             * Checks to see whether the given index is a valid column number
1488:             * in this <code>CachedRowSetXImpl</code> object and throws
1489:             * an <code>SQLException</code> if it is not. The index is out of bounds
1490:             * if it is less than <code>1</code> or greater than the number of
1491:             * columns in this rowset.
1492:             * <P>
1493:             * This method is called internally by the <code>getXXX</code> and
1494:             * <code>updateXXX</code> methods.
1495:             *
1496:             * @param idx the number of a column in this <code>CachedRowSetXImpl</code>
1497:             *            object; must be between <code>1</code> and the number of
1498:             *            rows in this rowset
1499:             * @throws SQLException if the given index is out of bounds
1500:             */
1501:            private void checkIndex(int idx) throws SQLException {
1502:                if (idx < 1 || idx > rowSetMD.getColumnCount()) {
1503:                    throw new SQLException(MessageFormat.format(rb
1504:                            .getString("INVALID_COLUMN_INDEX"), //NOI18N
1505:                            new Object[] { new Integer(idx) }));
1506:                }
1507:            }
1508:
1509:            /**
1510:             * Checks to see whether the cursor for this <code>CachedRowSetXImpl</code>
1511:             * object is on a row in the rowset and throws an
1512:             * <code>SQLException</code> if it is not.
1513:             * <P>
1514:             * This method is called internally by <code>getXXX</code> methods, by
1515:             * <code>updateXXX</code> methods, and by methods that update, insert,
1516:             * or delete a row or that cancel a row update, insert, or delete.
1517:             *
1518:             * @throws SQLException if the cursor for this <code>CachedRowSetXImpl</code>
1519:             *         object is not on a valid row
1520:             */
1521:            private void checkCursor() throws SQLException {
1522:                if (isAfterLast() == true || isBeforeFirst() == true) {
1523:                    throw new SQLException(rb.getString("INVALID_CURSOR_POS")); //NOI18N
1524:                }
1525:            }
1526:
1527:            /**
1528:             * Returns the column number of the column with the given name in this
1529:             * <code>CachedRowSetXImpl</code> object.  This method throws an
1530:             * <code>SQLException</code> if the given name is not the name of
1531:             * one of the columns in this rowset.
1532:             *
1533:             * @param name a <code>String</code> object that is the name of a column in
1534:             *              this <code>CachedRowSetXImpl</code> object
1535:             * @throws SQLException if the given name does not match the name of one of
1536:             *         the columns in this rowset
1537:             */
1538:            private int getColIdxByName(String name) throws SQLException {
1539:                int cols = rowSetMD.getColumnCount();
1540:
1541:                for (int i = 1; i <= cols; ++i) {
1542:                    String colName = rowSetMD.getColumnName(i);
1543:                    if (colName != null)
1544:                        if (name.equalsIgnoreCase(colName))
1545:                            return (i);
1546:                        else
1547:                            continue;
1548:                }
1549:                throw new SQLException(rb.getString("INVALID_COLUMN_NAME")); //NOI18N
1550:
1551:            }
1552:
1553:            /**
1554:             * Returns the insert row or the current row of this
1555:             * <code>CachedRowSetXImpl</code>object.
1556:             *
1557:             * @return the <code>Row</code> object on which this <code>CachedRowSetXImpl</code>
1558:             * objects's cursor is positioned
1559:             */
1560:            protected BaseRow getCurrentRow() throws SQLException {
1561:                if (onInsertRow == true) {
1562:                    return (BaseRow) insertRow;
1563:                } else {
1564:                    if (cursorPos < 1 || cursorPos > rvh.size()) {
1565:                        throw new SQLException(rb
1566:                                .getString("INVALID_CURSOR_POS")); //NOI18N
1567:                    }
1568:                    return (BaseRow) (rvh.get(cursorPos - 1));
1569:                }
1570:            }
1571:
1572:            /**
1573:             * Removes the row on which the cursor is positioned.
1574:             * <p>
1575:             * This is a implementation only method and is not required as a standard
1576:             * implementation of the <code>CachedRowSet</code> interface.
1577:             *
1578:             * @throws SQLException if the cursor is positioned on the insert
1579:             *            row
1580:             */
1581:            protected void removeCurrentRow() throws SQLException {
1582:                ((Row) getCurrentRow()).setDeleted();
1583:                rvh.remove(cursorPos);
1584:                --numRows;
1585:            }
1586:
1587:            /**
1588:             * {@inheritDoc}
1589:             */
1590:            public String getString(int columnIndex) throws SQLException {
1591:                checkExecuted();
1592:                Object value;
1593:
1594:                // sanity check.
1595:                checkIndex(columnIndex);
1596:                // make sure the cursor is on a valid row
1597:                checkCursor();
1598:
1599:                setLastValueNull(false);
1600:                value = getCurrentRow().getColumnObject(columnIndex);
1601:
1602:                // check for SQL NULL
1603:                if (value == null) {
1604:                    setLastValueNull(true);
1605:                    return null;
1606:                }
1607:
1608:                return value.toString();
1609:            }
1610:
1611:            /**
1612:             * {@inheritDoc}
1613:             */
1614:            public boolean getBoolean(int columnIndex) throws SQLException {
1615:                checkExecuted();
1616:                Object value;
1617:
1618:                // sanity check.
1619:                checkIndex(columnIndex);
1620:                // make sure the cursor is on a valid row
1621:                checkCursor();
1622:
1623:                setLastValueNull(false);
1624:                value = getCurrentRow().getColumnObject(columnIndex);
1625:
1626:                // check for SQL NULL
1627:                if (value == null) {
1628:                    setLastValueNull(true);
1629:                    return false;
1630:                }
1631:
1632:                // check for Boolean...
1633:                if (value instanceof  Boolean) {
1634:                    return ((Boolean) value).booleanValue();
1635:                }
1636:
1637:                // convert to a Double and compare to zero
1638:                try {
1639:                    Double d = new Double(value.toString());
1640:                    if (d.compareTo(new Double((double) 0)) == 0) {
1641:                        return false;
1642:                    } else {
1643:                        return true;
1644:                    }
1645:                } catch (NumberFormatException ex) {
1646:                    throw new SQLException(MessageFormat.format(rb
1647:                            .getString("GET_BOOLEAN_FAILED"), //NOI18N
1648:                            new Object[] { value.toString().trim(),
1649:                                    new Integer(columnIndex) }));
1650:                }
1651:            }
1652:
1653:            /**
1654:             * {@inheritDoc}
1655:             */
1656:            public byte getByte(int columnIndex) throws SQLException {
1657:                checkExecuted();
1658:                Object value;
1659:
1660:                // sanity check.
1661:                checkIndex(columnIndex);
1662:                // make sure the cursor is on a valid row
1663:                checkCursor();
1664:
1665:                setLastValueNull(false);
1666:                value = getCurrentRow().getColumnObject(columnIndex);
1667:
1668:                // check for SQL NULL
1669:                if (value == null) {
1670:                    setLastValueNull(true);
1671:                    return (byte) 0;
1672:                }
1673:                try {
1674:                    return ((new Byte(value.toString())).byteValue());
1675:                } catch (NumberFormatException ex) {
1676:                    throw new SQLException(MessageFormat.format(rb
1677:                            .getString("GET_BYTE_FAILED"), //NOI18N
1678:                            new Object[] { value.toString().trim(),
1679:                                    new Integer(columnIndex) }));
1680:                }
1681:            }
1682:
1683:            /**
1684:             * {@inheritDoc}
1685:             */
1686:            public short getShort(int columnIndex) throws SQLException {
1687:                checkExecuted();
1688:                Object value;
1689:
1690:                // sanity check.
1691:                checkIndex(columnIndex);
1692:                // make sure the cursor is on a valid row
1693:                checkCursor();
1694:
1695:                setLastValueNull(false);
1696:                value = getCurrentRow().getColumnObject(columnIndex);
1697:
1698:                // check for SQL NULL
1699:                if (value == null) {
1700:                    setLastValueNull(true);
1701:                    return (short) 0;
1702:                }
1703:
1704:                try {
1705:                    return ((new Short(value.toString().trim())).shortValue());
1706:                } catch (NumberFormatException ex) {
1707:                    throw new SQLException(MessageFormat.format(rb
1708:                            .getString("GET_SHORT_FAILED"), //NOI18N
1709:                            new Object[] { value.toString().trim(),
1710:                                    new Integer(columnIndex) }));
1711:                }
1712:            }
1713:
1714:            public int getInt(int columnIndex) throws SQLException {
1715:                checkExecuted();
1716:                Object value;
1717:
1718:                // sanity check.
1719:                checkIndex(columnIndex);
1720:                // make sure the cursor is on a valid row
1721:                checkCursor();
1722:
1723:                setLastValueNull(false);
1724:                value = getCurrentRow().getColumnObject(columnIndex);
1725:
1726:                // check for SQL NULL
1727:                if (value == null) {
1728:                    setLastValueNull(true);
1729:                    return (int) 0;
1730:                }
1731:
1732:                try {
1733:                    return ((new Integer(value.toString().trim())).intValue());
1734:                } catch (NumberFormatException ex) {
1735:                    throw new SQLException(MessageFormat.format(rb
1736:                            .getString("GET_INT_FAILED"), //NOI18N
1737:                            new Object[] { value.toString().trim(),
1738:                                    new Integer(columnIndex) }));
1739:                }
1740:            }
1741:
1742:            /**
1743:             * {@inheritDoc}
1744:             */
1745:            public long getLong(int columnIndex) throws SQLException {
1746:                checkExecuted();
1747:                Object value;
1748:
1749:                // sanity check.
1750:                checkIndex(columnIndex);
1751:                // make sure the cursor is on a valid row
1752:                checkCursor();
1753:
1754:                setLastValueNull(false);
1755:                value = getCurrentRow().getColumnObject(columnIndex);
1756:
1757:                // check for SQL NULL
1758:                if (value == null) {
1759:                    setLastValueNull(true);
1760:                    return (long) 0;
1761:                }
1762:                try {
1763:                    return ((new Long(value.toString().trim())).longValue());
1764:                } catch (NumberFormatException ex) {
1765:                    throw new SQLException(MessageFormat.format(rb
1766:                            .getString("GET_LONG_FAILED"), //NOI18N
1767:                            new Object[] { value.toString().trim(),
1768:                                    new Integer(columnIndex) }));
1769:                }
1770:            }
1771:
1772:            /**
1773:             * {@inheritDoc}
1774:             */
1775:            public float getFloat(int columnIndex) throws SQLException {
1776:                checkExecuted();
1777:                Object value;
1778:
1779:                // sanity check.
1780:                checkIndex(columnIndex);
1781:                // make sure the cursor is on a valid row
1782:                checkCursor();
1783:
1784:                setLastValueNull(false);
1785:                value = getCurrentRow().getColumnObject(columnIndex);
1786:
1787:                // check for SQL NULL
1788:                if (value == null) {
1789:                    setLastValueNull(true);
1790:                    return (float) 0;
1791:                }
1792:                try {
1793:                    return ((new Float(value.toString())).floatValue());
1794:                } catch (NumberFormatException ex) {
1795:                    throw new SQLException(MessageFormat.format(rb
1796:                            .getString("GET_FLOAT_FAILED"), //NOI18N
1797:                            new Object[] { value.toString().trim(),
1798:                                    new Integer(columnIndex) }));
1799:                }
1800:            }
1801:
1802:            /**
1803:             * {@inheritDoc}
1804:             */
1805:            public double getDouble(int columnIndex) throws SQLException {
1806:                checkExecuted();
1807:                Object value;
1808:
1809:                // sanity check.
1810:                checkIndex(columnIndex);
1811:                // make sure the cursor is on a valid row
1812:                checkCursor();
1813:
1814:                setLastValueNull(false);
1815:                value = getCurrentRow().getColumnObject(columnIndex);
1816:
1817:                // check for SQL NULL
1818:                if (value == null) {
1819:                    setLastValueNull(true);
1820:                    return (double) 0;
1821:                }
1822:                try {
1823:                    return ((new Double(value.toString().trim())).doubleValue());
1824:                } catch (NumberFormatException ex) {
1825:                    throw new SQLException(MessageFormat.format(rb
1826:                            .getString("GET_DOUBLE_FAILED"), //NOI18N
1827:                            new Object[] { value.toString().trim(),
1828:                                    new Integer(columnIndex) }));
1829:                }
1830:            }
1831:
1832:            /**
1833:             * {@inheritDoc}
1834:             */
1835:            public BigDecimal getBigDecimal(int columnIndex, int scale)
1836:                    throws SQLException {
1837:                checkExecuted();
1838:                return getBigDecimal(columnIndex, scale);
1839:            }
1840:
1841:            /**
1842:             * {@inheritDoc}
1843:             */
1844:            public byte[] getBytes(int columnIndex) throws SQLException {
1845:                checkExecuted();
1846:                // sanity check.
1847:                checkIndex(columnIndex);
1848:                // make sure the cursor is on a valid row
1849:                checkCursor();
1850:
1851:                if (isBinary(rowSetMD.getColumnType(columnIndex)) == false) {
1852:                    throw new SQLException(rb.getString("DATATYPE_MISMATCH")); //NOI18N
1853:                }
1854:
1855:                return (byte[]) (getCurrentRow().getColumnObject(columnIndex));
1856:            }
1857:
1858:            /**
1859:             * {@inheritDoc}
1860:             */
1861:            public java.sql.Date getDate(int columnIndex) throws SQLException {
1862:                checkExecuted();
1863:                Object value;
1864:
1865:                // sanity check.
1866:                checkIndex(columnIndex);
1867:                // make sure the cursor is on a valid row
1868:                checkCursor();
1869:
1870:                setLastValueNull(false);
1871:                value = getCurrentRow().getColumnObject(columnIndex);
1872:
1873:                // check for SQL NULL
1874:                if (value == null) {
1875:                    setLastValueNull(true);
1876:                    return null;
1877:                }
1878:
1879:                /*
1880:                 * The object coming back from the db could be
1881:                 * a date, a timestamp, or a char field variety.
1882:                 * If it's a date type return it, a timestamp
1883:                 * we turn into a long and then into a date,
1884:                 * char strings we try to parse. Yuck.
1885:                 */
1886:                switch (rowSetMD.getColumnType(columnIndex)) {
1887:                case java.sql.Types.DATE: {
1888:                    long sec = ((java.sql.Date) value).getTime();
1889:                    return new java.sql.Date(sec);
1890:                }
1891:                case java.sql.Types.TIMESTAMP: {
1892:                    long sec = ((java.sql.Timestamp) value).getTime();
1893:                    return new java.sql.Date(sec);
1894:                }
1895:                case java.sql.Types.CHAR:
1896:                case java.sql.Types.VARCHAR:
1897:                case java.sql.Types.LONGVARCHAR: {
1898:                    try {
1899:                        DateFormat df = DateFormat.getDateInstance();
1900:                        return ((java.sql.Date) (df.parse(value.toString())));
1901:                    } catch (ParseException ex) {
1902:                        throw new SQLException(MessageFormat.format(rb
1903:                                .getString("GET_TIMESTAMP_FAILED"), //NOI18N
1904:                                new Object[] { value.toString().trim(),
1905:                                        new Integer(columnIndex) }));
1906:                    }
1907:                }
1908:                default: {
1909:                    throw new SQLException(MessageFormat.format(rb
1910:                            .getString("GET_TIMESTAMP2_FAILED"), //NOI18N
1911:                            new Object[] { value.toString().trim(),
1912:                                    new Integer(columnIndex) }));
1913:                }
1914:                }
1915:            }
1916:
1917:            /**
1918:             * {@inheritDoc}
1919:             */
1920:            public java.sql.Time getTime(int columnIndex) throws SQLException {
1921:                checkExecuted();
1922:                Object value;
1923:
1924:                // sanity check.
1925:                checkIndex(columnIndex);
1926:                // make sure the cursor is on a valid row
1927:                checkCursor();
1928:
1929:                setLastValueNull(false);
1930:                value = getCurrentRow().getColumnObject(columnIndex);
1931:
1932:                // check for SQL NULL
1933:                if (value == null) {
1934:                    setLastValueNull(true);
1935:                    return null;
1936:                }
1937:
1938:                /*
1939:                 * The object coming back from the db could be
1940:                 * a date, a timestamp, or a char field variety.
1941:                 * If it's a date type return it, a timestamp
1942:                 * we turn into a long and then into a date,
1943:                 * char strings we try to parse. Yuck.
1944:                 */
1945:                switch (rowSetMD.getColumnType(columnIndex)) {
1946:                case java.sql.Types.TIME: {
1947:                    return (java.sql.Time) value;
1948:                }
1949:                case java.sql.Types.TIMESTAMP: {
1950:                    long sec = ((java.sql.Timestamp) value).getTime();
1951:                    return new java.sql.Time(sec);
1952:                }
1953:                case java.sql.Types.CHAR:
1954:                case java.sql.Types.VARCHAR:
1955:                case java.sql.Types.LONGVARCHAR: {
1956:                    try {
1957:                        DateFormat tf = DateFormat.getTimeInstance();
1958:                        return ((java.sql.Time) (tf.parse(value.toString())));
1959:                    } catch (ParseException ex) {
1960:                        throw new SQLException(MessageFormat.format(rb
1961:                                .getString("GET_TIME_FAILED"), //NOI18N
1962:                                new Object[] { value.toString().trim(),
1963:                                        new Integer(columnIndex) }));
1964:                    }
1965:                }
1966:                default: {
1967:                    throw new SQLException(MessageFormat.format(rb
1968:                            .getString("GET_TIME2_FAILED"), //NOI18N
1969:                            new Object[] { value.toString().trim(),
1970:                                    new Integer(columnIndex) }));
1971:                }
1972:                }
1973:            }
1974:
1975:            /**
1976:             * {@inheritDoc}
1977:             */
1978:            public java.sql.Timestamp getTimestamp(int columnIndex)
1979:                    throws SQLException {
1980:                // System.out.println("Entering CRSXI.getTimestamp");
1981:                checkExecuted();
1982:                Object value;
1983:
1984:                // sanity check.
1985:                checkIndex(columnIndex);
1986:                // make sure the cursor is on a valid row
1987:                checkCursor();
1988:
1989:                setLastValueNull(false);
1990:                value = getCurrentRow().getColumnObject(columnIndex);
1991:                // System.out.println("CRSXI.getTimestamp/1, value: " + value);
1992:
1993:                // check for SQL NULL
1994:                if (value == null) {
1995:                    setLastValueNull(true);
1996:                    return null;
1997:                }
1998:
1999:                /*
2000:                 * The object coming back from the db could be
2001:                 * a date, a timestamp, or a char field variety.
2002:                 * If it's a date type return it; a timestamp
2003:                 * we turn into a long and then into a date;
2004:                 * char strings we try to parse. Yuck.
2005:                 */
2006:                // System.out.println("CRSXI.getTimestamp/2, columnType: " + rowSetMD.getColumnType(columnIndex));
2007:                switch (rowSetMD.getColumnType(columnIndex)) {
2008:                case java.sql.Types.TIMESTAMP: {
2009:                    return (java.sql.Timestamp) value;
2010:                }
2011:                case java.sql.Types.TIME: {
2012:                    long sec = ((java.sql.Time) value).getTime();
2013:                    return new java.sql.Timestamp(sec);
2014:                }
2015:                case java.sql.Types.DATE: {
2016:                    long sec = ((java.sql.Date) value).getTime();
2017:                    return new java.sql.Timestamp(sec);
2018:                }
2019:                case java.sql.Types.CHAR:
2020:                case java.sql.Types.VARCHAR:
2021:                case java.sql.Types.LONGVARCHAR: {
2022:                    try {
2023:                        DateFormat tf = DateFormat.getTimeInstance();
2024:                        return ((java.sql.Timestamp) (tf
2025:                                .parse(value.toString())));
2026:                    } catch (ParseException ex) {
2027:                        throw new SQLException(MessageFormat.format(rb
2028:                                .getString("GET_TIMESTAMP_FAILED"), //NOI18N
2029:                                new Object[] { value.toString().trim(),
2030:                                        new Integer(columnIndex) }));
2031:                    }
2032:                }
2033:                default: {
2034:                    throw new SQLException(MessageFormat.format(rb
2035:                            .getString("GET_TIMESTAMP2_FAILED"), //NOI18N
2036:                            new Object[] { value.toString().trim(),
2037:                                    new Integer(columnIndex) }));
2038:                }
2039:                }
2040:            }
2041:
2042:            /**
2043:             * {@inheritDoc}
2044:             */
2045:            public java.io.InputStream getAsciiStream(int columnIndex)
2046:                    throws SQLException {
2047:                checkExecuted();
2048:                Object value;
2049:
2050:                // always free an old stream
2051:                asciiStream = null;
2052:
2053:                // sanity check
2054:                checkIndex(columnIndex);
2055:                //make sure the cursor is on a vlid row
2056:                checkCursor();
2057:
2058:                value = getCurrentRow().getColumnObject(columnIndex);
2059:                if (value == null) {
2060:                    lastValueNull = true;
2061:                    return null;
2062:                }
2063:
2064:                try {
2065:                    if (isString(rowSetMD.getColumnType(columnIndex))) {
2066:                        asciiStream = new ByteArrayInputStream(((String) value)
2067:                                .getBytes("ASCII")); //NOI18N
2068:                    } else {
2069:                        throw new SQLException(rb
2070:                                .getString("DATATYPE_MISMATCH")); //NOI18N
2071:                    }
2072:                } catch (java.io.UnsupportedEncodingException ex) {
2073:                    throw new SQLException(ex.getMessage());
2074:                }
2075:
2076:                return (java.io.InputStream) asciiStream;
2077:            }
2078:
2079:            /**
2080:             * {@inheritDoc}
2081:             */
2082:            public java.io.InputStream getUnicodeStream(int columnIndex)
2083:                    throws SQLException {
2084:                checkExecuted();
2085:                // always free an old stream
2086:                unicodeStream = null;
2087:
2088:                // sanity check.
2089:                checkIndex(columnIndex);
2090:                // make sure the cursor is on a valid row
2091:                checkCursor();
2092:
2093:                if (isBinary(rowSetMD.getColumnType(columnIndex)) == false
2094:                        && isString(rowSetMD.getColumnType(columnIndex)) == false) {
2095:                    throw new SQLException(rb.getString("DATATYPE_MISMATCH")); //NOI18N
2096:                }
2097:
2098:                Object value = getCurrentRow().getColumnObject(columnIndex);
2099:                if (value == null) {
2100:                    lastValueNull = true;
2101:                    return null;
2102:                }
2103:
2104:                unicodeStream = new StringBufferInputStream(value.toString());
2105:
2106:                return (java.io.InputStream) unicodeStream;
2107:            }
2108:
2109:            /**
2110:             * {@inheritDoc}
2111:             */
2112:            public java.io.InputStream getBinaryStream(int columnIndex)
2113:                    throws SQLException {
2114:                checkExecuted();
2115:
2116:                // always free an old stream
2117:                binaryStream = null;
2118:
2119:                // sanity check.
2120:                checkIndex(columnIndex);
2121:                // make sure the cursor is on a valid row
2122:                checkCursor();
2123:
2124:                if (isBinary(rowSetMD.getColumnType(columnIndex)) == false) {
2125:                    throw new SQLException(rb.getString("DATATYPE_MISMATCH")); //NOI18N
2126:                }
2127:
2128:                Object value = getCurrentRow().getColumnObject(columnIndex);
2129:                if (value == null) {
2130:                    lastValueNull = true;
2131:                    return null;
2132:                }
2133:
2134:                binaryStream = new ByteArrayInputStream((byte[]) value);
2135:
2136:                return (java.io.InputStream) binaryStream;
2137:
2138:            }
2139:
2140:            //======================================================================
2141:            // Methods for accessing results by column name
2142:            //======================================================================
2143:
2144:            /**
2145:             * {@inheritDoc}
2146:             */
2147:            public String getString(String columnName) throws SQLException {
2148:                checkExecuted();
2149:                return getString(getColIdxByName(columnName));
2150:            }
2151:
2152:            /**
2153:             * {@inheritDoc}
2154:             */
2155:            public boolean getBoolean(String columnName) throws SQLException {
2156:                checkExecuted();
2157:                return getBoolean(getColIdxByName(columnName));
2158:            }
2159:
2160:            /**
2161:             * {@inheritDoc}
2162:             */
2163:            public byte getByte(String columnName) throws SQLException {
2164:                checkExecuted();
2165:                return getByte(getColIdxByName(columnName));
2166:            }
2167:
2168:            /**
2169:             * {@inheritDoc}
2170:             */
2171:            public short getShort(String columnName) throws SQLException {
2172:                checkExecuted();
2173:                return getShort(getColIdxByName(columnName));
2174:            }
2175:
2176:            /**
2177:             * {@inheritDoc}
2178:             */
2179:            public int getInt(String columnName) throws SQLException {
2180:                checkExecuted();
2181:                return getInt(getColIdxByName(columnName));
2182:            }
2183:
2184:            /**
2185:             * {@inheritDoc}
2186:             */
2187:            public long getLong(String columnName) throws SQLException {
2188:                checkExecuted();
2189:                return getLong(getColIdxByName(columnName));
2190:            }
2191:
2192:            /**
2193:             * {@inheritDoc}
2194:             */
2195:            public float getFloat(String columnName) throws SQLException {
2196:                checkExecuted();
2197:                return getFloat(getColIdxByName(columnName));
2198:            }
2199:
2200:            /**
2201:             * {@inheritDoc}
2202:             */
2203:            public double getDouble(String columnName) throws SQLException {
2204:                checkExecuted();
2205:                return getDouble(getColIdxByName(columnName));
2206:            }
2207:
2208:            /**
2209:             * {@inheritDoc}
2210:             */
2211:            public BigDecimal getBigDecimal(String columnName, int scale)
2212:                    throws SQLException {
2213:                checkExecuted();
2214:                return getBigDecimal(getColIdxByName(columnName), scale);
2215:            }
2216:
2217:            /**
2218:             * {@inheritDoc}
2219:             */
2220:            public byte[] getBytes(String columnName) throws SQLException {
2221:                checkExecuted();
2222:                return getBytes(getColIdxByName(columnName));
2223:            }
2224:
2225:            /**
2226:             * {@inheritDoc}
2227:             */
2228:            public java.sql.Date getDate(String columnName) throws SQLException {
2229:                checkExecuted();
2230:                return getDate(getColIdxByName(columnName));
2231:            }
2232:
2233:            /**
2234:             * {@inheritDoc}
2235:             */
2236:            public java.sql.Time getTime(String columnName) throws SQLException {
2237:                checkExecuted();
2238:                return getTime(getColIdxByName(columnName));
2239:            }
2240:
2241:            /**
2242:             * {@inheritDoc}
2243:             */
2244:            public java.sql.Timestamp getTimestamp(String columnName)
2245:                    throws SQLException {
2246:                checkExecuted();
2247:                return getTimestamp(getColIdxByName(columnName));
2248:            }
2249:
2250:            /**
2251:             * {@inheritDoc}
2252:             */
2253:            public java.io.InputStream getAsciiStream(String columnName)
2254:                    throws SQLException {
2255:                checkExecuted();
2256:                return getAsciiStream(getColIdxByName(columnName));
2257:
2258:            }
2259:
2260:            /**
2261:             * {@inheritDoc}
2262:             */
2263:            public java.io.InputStream getUnicodeStream(String columnName)
2264:                    throws SQLException {
2265:                checkExecuted();
2266:                return getUnicodeStream(getColIdxByName(columnName));
2267:            }
2268:
2269:            /**
2270:             * {@inheritDoc}
2271:             */
2272:            public java.io.InputStream getBinaryStream(String columnName)
2273:                    throws SQLException {
2274:                checkExecuted();
2275:                return getBinaryStream(getColIdxByName(columnName));
2276:            }
2277:
2278:            //=====================================================================
2279:            // Advanced features:
2280:            //=====================================================================
2281:
2282:            /**
2283:             * {@inheritDoc}
2284:             */
2285:            public SQLWarning getWarnings() {
2286:                return sqlwarn;
2287:            }
2288:
2289:            /**
2290:             * {@inheritDoc}
2291:             */
2292:            public void clearWarnings() {
2293:                sqlwarn = null;
2294:            }
2295:
2296:            /**
2297:             * {@inheritDoc}
2298:             */
2299:            public String getCursorName() throws SQLException {
2300:                throw new SQLException(rb
2301:                        .getString("POSITIONED_UPDATES_NOT_SUPPORTED")); //NOI18N
2302:            }
2303:
2304:            /**
2305:             * {@inheritDoc}
2306:             */
2307:            public ResultSetMetaData getMetaData() throws SQLException {
2308:
2309:                Log.getLogger().entering(getClass().getName(), "getMetaData()");
2310:
2311:                // if we haven't yet executed, rowSetMD will be null.
2312:                // we don't want to execute here, so let's get a connection
2313:                // and manufacture the rowsetmd
2314:                if (rowSetMD == null) {
2315:
2316:                    Connection tempConn = null;
2317:                    PreparedStatement tempPS = null;
2318:                    try {
2319:                        tempConn = getConnection(getDataSourceName(), getUrl(),
2320:                                getUsername(), getPassword());
2321:                        Log.getLogger().finest(
2322:                                "Connection: " + tempConn
2323:                                        + "  DataSourceName: "
2324:                                        + getDataSourceName() + "  URL: "
2325:                                        + getUrl());
2326:                        tempPS = tempConn.prepareStatement(getCommand());
2327:                        // System.out.println("Prepared Statement: " + tempPS);
2328:
2329:                        rowSetMD = new RowSetMetaDataXImpl();
2330:                        ResultSetMetaData rsmd;
2331:                        try {
2332:                            rsmd = tempPS.getMetaData();
2333:                            Log.getLogger().finest(
2334:                                    "After calling tempPS.getMetaData(), rsmd: "
2335:                                            + rsmd);
2336:
2337:                            if (rsmd == null
2338:                                    && "Oracle".equals(tempConn.getMetaData()
2339:                                            .getDatabaseProductName())) {
2340:                                // Oracle 9 driver problem -- silently returns null rsmd
2341:                                rsmd = oracleFixup(tempConn, getCommand());
2342:                            }
2343:                        } catch (SQLException e) {
2344:
2345:                            Log.getLogger().finest(
2346:                                    "Exception caught: " + e.getErrorCode()
2347:                                            + " : " + e.getMessage());
2348:                            if (e.getErrorCode() == 17144) {
2349:                                // Oracle 10 driver problem -- throws SQLException, "statement handle not executed"
2350:                                rsmd = oracleFixup(tempConn, getCommand());
2351:
2352:                            } else {
2353:                                // Some other problem.  Re-throw.
2354:                                throw (e);
2355:                            }
2356:                        }
2357:
2358:                        initMetaData(rowSetMD, rsmd);
2359:                        // System.out.println("After calling initMetaData, rsmd: " + rsmd);
2360:                    }
2361:                    // catch (SQLException e) {
2362:                    // }
2363:                    finally {
2364:                        if (tempPS != null) {
2365:                            tempPS.close();
2366:                        }
2367:                        if (tempConn != null) {
2368:                            try {
2369:                                if (!tempConn.getAutoCommit()) {
2370:                                    tempConn.rollback();
2371:                                }
2372:                            } catch (Exception dummy) {
2373:                                /*
2374:                                 * not an error condition, we're closing anyway, but
2375:                                 * we'd like to clean up any locks if we can since
2376:                                 * it is not clear the connection pool will clean
2377:                                 * these connections in a timely manner
2378:                                 */
2379:                            }
2380:                            tempConn.close();
2381:                        }
2382:                    }
2383:                }
2384:                Log.getLogger().exiting(getClass().getName(), "getMetaData()");
2385:                return rowSetMD;
2386:            }
2387:
2388:            // Work around Oracle driver problem by executing modified command, to populate metadata
2389:            // Strip off unnecessary stuff, and add where clause that is always false
2390:            private ResultSetMetaData oracleFixup(Connection tempConn,
2391:                    String command) throws SQLException {
2392:                Log.getLogger().entering("CachedRowSetXImpl", "oracleFixup()",
2393:                        command);
2394:                String cmd = command;
2395:
2396:                // Extract the GROUP BY, to use later
2397:                String groupBy = "";
2398:                int pos = cmd.toUpperCase().indexOf("GROUP BY");
2399:                if (pos != -1) {
2400:                    groupBy = cmd.substring(pos);
2401:                    cmd = cmd.substring(0, pos);
2402:                }
2403:
2404:                // Retain SELECT/FROM, remove WHERE/HAVING/ORDER BY
2405:                String[] parts = cmd.split("(?i:where|having|order by)");
2406:
2407:                // Attach new WHERE clause, previous GROUP BY
2408:                String newCommand = parts[0] + " WHERE 1=0 " + groupBy;
2409:
2410:                Log.getLogger().finest(
2411:                        "Executing modified statement: " + newCommand);
2412:                PreparedStatement tempPS = tempConn
2413:                        .prepareStatement(newCommand);
2414:                tempPS.execute();
2415:                return tempPS.getMetaData();
2416:            }
2417:
2418:            /**
2419:             * {@inheritDoc}
2420:             */
2421:            public Object getObject(int columnIndex) throws SQLException {
2422:                checkExecuted();
2423:                Object value;
2424:                java.util.Map map;
2425:
2426:                // sanity check.
2427:                checkIndex(columnIndex);
2428:                // make sure the cursor is on a valid row
2429:                checkCursor();
2430:
2431:                setLastValueNull(false);
2432:                value = getCurrentRow().getColumnObject(columnIndex);
2433:
2434:                // check for SQL NULL
2435:                if (value == null) {
2436:                    setLastValueNull(true);
2437:                    return null;
2438:                }
2439:                if (value instanceof  Struct) {
2440:                    Struct s = (Struct) value;
2441:                    map = getTypeMap();
2442:                    // look up the class in the map
2443:                    Class c = (Class) map.get(s.getSQLTypeName());
2444:                    if (c != null) {
2445:                        // create new instance of the class
2446:                        SQLData obj = null;
2447:                        try {
2448:                            obj = (SQLData) c.newInstance();
2449:                        } catch (java.lang.InstantiationException ex) {
2450:                            throw new SQLException(rb
2451:                                    .getString("UNABLE_TO_INSTANTIATE")
2452:                                    + ex.getMessage()); //NOI18N
2453:                        } catch (java.lang.IllegalAccessException ex) {
2454:                            throw new SQLException(rb
2455:                                    .getString("UNABLE_TO_INSTANTIATE")
2456:                                    + ex.getMessage()); //NOI18N
2457:                        }
2458:                        // get the attributes from the struct
2459:                        Object attribs[] = s.getAttributes(map);
2460:                        // create the SQLInput "stream"
2461:                        SQLInputImpl sqlInput = new SQLInputImpl(attribs, map);
2462:                        // read the values...
2463:                        obj.readSQL(sqlInput, s.getSQLTypeName());
2464:                        return (Object) obj;
2465:                    }
2466:                }
2467:                return value;
2468:            }
2469:
2470:            /**
2471:             * {@inheritDoc}
2472:             */
2473:            public Object getObject(String columnName) throws SQLException {
2474:                checkExecuted();
2475:                return getObject(getColIdxByName(columnName));
2476:            }
2477:
2478:            //----------------------------------------------------------------
2479:
2480:            /**
2481:             * {@inheritDoc}
2482:             */
2483:            public int findColumn(String columnName) throws SQLException {
2484:                return getColIdxByName(columnName);
2485:            }
2486:
2487:            //--------------------------JDBC 2.0-----------------------------------
2488:
2489:            //---------------------------------------------------------------------
2490:            // Getter's and Setter's
2491:            //---------------------------------------------------------------------
2492:
2493:            /**
2494:             * {@inheritDoc}
2495:             */
2496:            public java.io.Reader getCharacterStream(int columnIndex)
2497:                    throws SQLException {
2498:                checkExecuted();
2499:
2500:                // sanity check.
2501:                checkIndex(columnIndex);
2502:                // make sure the cursor is on a valid row
2503:                checkCursor();
2504:
2505:                if (isBinary(rowSetMD.getColumnType(columnIndex))) {
2506:                    Object value = getCurrentRow().getColumnObject(columnIndex);
2507:                    if (value == null) {
2508:                        lastValueNull = true;
2509:                        return null;
2510:                    }
2511:                    charStream = new InputStreamReader(
2512:                            new ByteArrayInputStream((byte[]) value));
2513:                } else if (isString(rowSetMD.getColumnType(columnIndex))) {
2514:                    Object value = getCurrentRow().getColumnObject(columnIndex);
2515:                    if (value == null) {
2516:                        lastValueNull = true;
2517:                        return null;
2518:                    }
2519:                    charStream = new StringReader(value.toString());
2520:                } else {
2521:                    throw new SQLException(rb.getString("DATATYPE_MISMATCH")); //NOI18N
2522:                }
2523:
2524:                return (java.io.Reader) charStream;
2525:            }
2526:
2527:            /**
2528:             * {@inheritDoc}
2529:             */
2530:            public java.io.Reader getCharacterStream(String columnName)
2531:                    throws SQLException {
2532:                checkExecuted();
2533:                return getCharacterStream(getColIdxByName(columnName));
2534:            }
2535:
2536:            /**
2537:             * {@inheritDoc}
2538:             */
2539:            public BigDecimal getBigDecimal(int columnIndex)
2540:                    throws SQLException {
2541:                checkExecuted();
2542:                Object value;
2543:
2544:                // sanity check.
2545:                checkIndex(columnIndex);
2546:                // make sure the cursor is on a valid row
2547:                checkCursor();
2548:
2549:                setLastValueNull(false);
2550:                value = getCurrentRow().getColumnObject(columnIndex);
2551:
2552:                // check for SQL NULL
2553:                if (value == null) {
2554:                    setLastValueNull(true);
2555:                    return null;
2556:                }
2557:                try {
2558:                    return (new BigDecimal(value.toString().trim()));
2559:                } catch (NumberFormatException ex) {
2560:                    throw new SQLException(MessageFormat.format(rb
2561:                            .getString("GET_DOUBLE_FAILED"), //NOI18N
2562:                            new Object[] { value.toString().trim(),
2563:                                    new Integer(columnIndex) }));
2564:                }
2565:            }
2566:
2567:            /**
2568:             * {@inheritDoc}
2569:             */
2570:            public BigDecimal getBigDecimal(String columnName)
2571:                    throws SQLException {
2572:                checkExecuted();
2573:                return getBigDecimal(getColIdxByName(columnName));
2574:            }
2575:
2576:            //---------------------------------------------------------------------
2577:            // Traversal/Positioning
2578:            //---------------------------------------------------------------------
2579:
2580:            /**
2581:             * {@inheritDoc}
2582:             */
2583:            public int size() {
2584:                // checkExecuted(); !JK Doesn't allow SQLException!
2585:                return numRows;
2586:            }
2587:
2588:            /**
2589:             * {@inheritDoc}
2590:             */
2591:            public boolean isBeforeFirst() throws SQLException {
2592:                checkExecuted();
2593:                if (cursorPos == 0 && numRows > 0) {
2594:                    return true;
2595:                } else {
2596:                    return false;
2597:                }
2598:            }
2599:
2600:            /**
2601:             * {@inheritDoc}
2602:             */
2603:            public boolean isAfterLast() throws SQLException {
2604:                checkExecuted();
2605:                if (cursorPos == numRows + 1 && numRows > 0) {
2606:                    return true;
2607:                } else {
2608:                    return false;
2609:                }
2610:            }
2611:
2612:            /**
2613:             * {@inheritDoc}
2614:             */
2615:            public boolean isFirst() throws SQLException {
2616:                checkExecuted();
2617:                // this becomes nasty because of deletes.
2618:                int saveCursorPos = cursorPos;
2619:                int saveAbsoluteCursorPos = absolutePos;
2620:                internalFirst();
2621:                if (cursorPos == saveCursorPos) {
2622:                    return true;
2623:                } else {
2624:                    cursorPos = saveCursorPos;
2625:                    absolutePos = saveAbsoluteCursorPos;
2626:                    return false;
2627:                }
2628:            }
2629:
2630:            /**
2631:             * {@inheritDoc}
2632:             */
2633:            public boolean isLast() throws SQLException {
2634:                checkExecuted();
2635:                int saveCursorPos = cursorPos;
2636:                int saveAbsoluteCursorPos = absolutePos;
2637:                boolean saveShowDeleted = getShowDeleted();
2638:                setShowDeleted(true);
2639:                internalLast();
2640:                if (cursorPos == saveCursorPos) {
2641:                    setShowDeleted(saveShowDeleted);
2642:                    return true;
2643:                } else {
2644:                    setShowDeleted(saveShowDeleted);
2645:                    cursorPos = saveCursorPos;
2646:                    absolutePos = saveAbsoluteCursorPos;
2647:                    return false;
2648:                }
2649:            }
2650:
2651:            /**
2652:             * {@inheritDoc}
2653:             */
2654:            public void beforeFirst() throws SQLException {
2655:                checkExecuted();
2656:                if (getType() == ResultSet.TYPE_FORWARD_ONLY) {
2657:                    throw new SQLException(rb
2658:                            .getString("RESULTSET_TYPE_FORWARD_ONLY")); //NOI18N
2659:                }
2660:                cursorPos = 0;
2661:                absolutePos = 0;
2662:                notifyCursorMoved();
2663:            }
2664:
2665:            /**
2666:             * {@inheritDoc}
2667:             */
2668:            public void afterLast() throws SQLException {
2669:                checkExecuted();
2670:                if (numRows > 0) {
2671:                    cursorPos = numRows + 1;
2672:                    absolutePos = 0;
2673:                    notifyCursorMoved();
2674:                }
2675:            }
2676:
2677:            /**
2678:             * {@inheritDoc}
2679:             */
2680:            public boolean first() throws SQLException {
2681:                checkExecuted();
2682:                if (getType() == ResultSet.TYPE_FORWARD_ONLY) {
2683:                    throw new SQLException(rb
2684:                            .getString("RESULTSET_TYPE_FORWARD_ONLY")); //NOI18N
2685:                }
2686:
2687:                // move and notify
2688:                boolean ret = this .internalFirst();
2689:                notifyCursorMoved();
2690:
2691:                return ret;
2692:            }
2693:
2694:            protected boolean internalFirst() throws SQLException {
2695:                boolean ret = false;
2696:
2697:                if (numRows > 0) {
2698:                    cursorPos = 1;
2699:                    if ((getShowDeleted() == false) && (rowDeleted() == true)) {
2700:                        ret = internalNext();
2701:                    } else {
2702:                        ret = true;
2703:                    }
2704:                }
2705:
2706:                if (ret == true)
2707:                    absolutePos = 1;
2708:                else
2709:                    absolutePos = 0;
2710:
2711:                return ret;
2712:            }
2713:
2714:            /**
2715:             * {@inheritDoc}
2716:             */
2717:            public boolean last() throws SQLException {
2718:                checkExecuted();
2719:                if (getType() == ResultSet.TYPE_FORWARD_ONLY) {
2720:                    throw new SQLException(rb
2721:                            .getString("RESULTSET_TYPE_FORWARD_ONLY")); //NOI18N
2722:                }
2723:
2724:                // move and notify
2725:                boolean ret = this .internalLast();
2726:                notifyCursorMoved();
2727:
2728:                return ret;
2729:            }
2730:
2731:            protected boolean internalLast() throws SQLException {
2732:                boolean ret = false;
2733:
2734:                if (numRows > 0) {
2735:                    cursorPos = numRows;
2736:                    if ((getShowDeleted() == false) && (rowDeleted() == true)) {
2737:                        ret = internalPrevious();
2738:                    } else {
2739:                        ret = true;
2740:                    }
2741:                }
2742:                if (ret == true)
2743:                    absolutePos = numRows - numDeleted;
2744:                else
2745:                    absolutePos = 0;
2746:                return ret;
2747:            }
2748:
2749:            /**
2750:             * {@inheritDoc}
2751:             */
2752:            public int getRow() throws SQLException {
2753:                checkExecuted();
2754:                // are we on a valid row? Valid rows are between first and last
2755:                if (numRows > 0 && cursorPos > 0 && cursorPos < (numRows + 1)
2756:                        && (getShowDeleted() == false && rowDeleted() == false)) {
2757:                    return absolutePos;
2758:                } else if (getShowDeleted() == true) {
2759:                    return cursorPos;
2760:                } else {
2761:                    return 0;
2762:                }
2763:            }
2764:
2765:            /**
2766:             * {@inheritDoc}
2767:             */
2768:            public boolean absolute(int row) throws SQLException {
2769:                checkExecuted();
2770:                if (row == 0 || getType() == ResultSet.TYPE_FORWARD_ONLY) {
2771:                    throw new SQLException(rb
2772:                            .getString("RESULTSET_TYPE_FORWARD_ONLY")); //NOI18N
2773:                }
2774:
2775:                if (row > 0) { // we are moving foward
2776:                    if (row > numRows) {
2777:                        // fell off the end
2778:                        afterLast();
2779:                        return false;
2780:                    } else {
2781:                        if (absolutePos <= 0)
2782:                            internalFirst();
2783:                    }
2784:                } else { // we are moving backward
2785:                    if (cursorPos + row < 0) {
2786:                        // fell off the front
2787:                        beforeFirst();
2788:                        return false;
2789:                    } else {
2790:                        if (absolutePos >= 0)
2791:                            internalLast();
2792:                    }
2793:                }
2794:
2795:                // Now move towards the absolute row that we're looking for
2796:                while (absolutePos != row) {
2797:                    if (absolutePos < row) {
2798:                        if (!internalNext())
2799:                            break;
2800:                    } else {
2801:                        if (!internalPrevious())
2802:                            break;
2803:                    }
2804:                }
2805:
2806:                notifyCursorMoved();
2807:
2808:                if (isAfterLast() || isBeforeFirst()) {
2809:                    return false;
2810:                } else {
2811:                    return true;
2812:                }
2813:            }
2814:
2815:            /**
2816:             * {@inheritDoc}
2817:             */
2818:            public boolean relative(int rows) throws SQLException {
2819:                checkExecuted();
2820:                if (numRows == 0 || isBeforeFirst() || isAfterLast()
2821:                        || getType() == ResultSet.TYPE_FORWARD_ONLY) {
2822:                    throw new SQLException(rb
2823:                            .getString("RESULTSET_TYPE_FORWARD_ONLY")); //NOI18N
2824:                }
2825:
2826:                if (rows == 0) {
2827:                    return true;
2828:                }
2829:
2830:                if (rows > 0) { // we are moving forward
2831:                    if (cursorPos + rows > numRows) {
2832:                        // fell off the end
2833:                        afterLast();
2834:                    } else {
2835:                        for (int i = 0; i < rows; i++) {
2836:                            if (!internalNext())
2837:                                break;
2838:                        }
2839:                    }
2840:                } else { // we are moving backward
2841:                    if (cursorPos + rows < 0) {
2842:                        // fell off the front
2843:                        beforeFirst();
2844:                    } else {
2845:                        for (int i = rows; i < 0; i++) {
2846:                            if (!internalPrevious())
2847:                                break;
2848:                        }
2849:                    }
2850:                }
2851:                notifyCursorMoved();
2852:
2853:                if (isAfterLast() || isBeforeFirst()) {
2854:                    return false;
2855:                } else {
2856:                    return true;
2857:                }
2858:            }
2859:
2860:            /**
2861:             * {@inheritDoc}
2862:             */
2863:            public boolean previous() throws SQLException {
2864:                checkExecuted();
2865:                if (getType() == ResultSet.TYPE_FORWARD_ONLY) {
2866:                    throw new SQLException(rb
2867:                            .getString("RESULTSET_TYPE_FORWARD_ONLY")); //NOI18N
2868:                }
2869:                /*
2870:                 * make sure things look sane. The cursor must be
2871:                 * positioned in the rowset or before first (0) or
2872:                 * after last (numRows + 1)
2873:                 */
2874:                if (cursorPos < 0 || cursorPos > numRows + 1) {
2875:                    throw new SQLException(rb.getString("INVALID_CURSOR_POS")); //NOI18N
2876:                }
2877:                // move and notify
2878:                boolean ret = this .internalPrevious();
2879:                notifyCursorMoved();
2880:
2881:                return ret;
2882:            }
2883:
2884:            protected boolean internalPrevious() throws SQLException {
2885:                boolean ret = false;
2886:
2887:                do {
2888:                    if (cursorPos > 1) {
2889:                        --cursorPos;
2890:                        ret = true;
2891:                    } else if (cursorPos == 1) {
2892:                        // decrement to before first
2893:                        --cursorPos;
2894:                        ret = false;
2895:                        break;
2896:                    }
2897:                } while ((getShowDeleted() == false) && (rowDeleted() == true));
2898:
2899:                /*
2900:                 * Each call to internalPrevious may move the cursor
2901:                 * over multiple rows, the absolute postion moves one one row
2902:                 */
2903:                if (ret == true)
2904:                    --absolutePos;
2905:                else
2906:                    absolutePos = 0;
2907:
2908:                return ret;
2909:            }
2910:
2911:            //---------------------------------------------------------------------
2912:            // Updates
2913:            //---------------------------------------------------------------------
2914:
2915:            /**
2916:             * {@inheritDoc}
2917:             */
2918:            public boolean rowUpdated() throws SQLException {
2919:                checkExecuted();
2920:                // make sure the cursor is on a valid row
2921:                checkCursor();
2922:                if (onInsertRow == true) {
2923:                    throw new SQLException(rb
2924:                            .getString("INVALID_INSERT_ROW_OP")); // NOI18N
2925:                }
2926:                return (((Row) getCurrentRow()).getUpdated());
2927:            }
2928:
2929:            /**
2930:             * {@inheritDoc}
2931:             */
2932:            public boolean columnUpdated(int idx) throws SQLException {
2933:                checkExecuted();
2934:                // make sure the cursor is on a valid row
2935:                checkCursor();
2936:                if (onInsertRow == true) {
2937:                    throw new SQLException(rb
2938:                            .getString("INVALID_INSERT_ROW_OP")); // NOI18N
2939:                }
2940:                return (((Row) getCurrentRow()).getColUpdated(idx - 1));
2941:            }
2942:
2943:            /**
2944:             * {@inheritDoc}
2945:             */
2946:            public boolean columnUpdated(String columnName) throws SQLException {
2947:                checkExecuted();
2948:                return columnUpdated(getColIdxByName(columnName));
2949:            }
2950:
2951:            /**
2952:             * {@inheritDoc}
2953:             */
2954:            public boolean rowInserted() throws SQLException {
2955:                checkExecuted();
2956:                // make sure the cursor is on a valid row
2957:                checkCursor();
2958:                if (onInsertRow == true) {
2959:                    throw new SQLException(rb
2960:                            .getString("INVALID_INSERT_ROW_OP")); // NOI18N
2961:                }
2962:                return (((Row) getCurrentRow()).getInserted());
2963:            }
2964:
2965:            /**
2966:             * {@inheritDoc}
2967:             */
2968:            public boolean rowDeleted() throws SQLException {
2969:                checkExecuted();
2970:                // make sure the cursor is on a valid row
2971:
2972:                if (isAfterLast() == true || isBeforeFirst() == true
2973:                        || onInsertRow == true) {
2974:
2975:                    throw new SQLException(rb.getString("INVALID_CURSOR_POS")); //NOI18N
2976:                }
2977:                return (((Row) getCurrentRow()).getDeleted());
2978:            }
2979:
2980:            /**
2981:             * Indicates whether the given SQL data type is a numberic type.
2982:             *
2983:             * @param type one of the constants from <code>java.sql.Types</code>
2984:             * @return <code>true</code> if the given type is <code>NUMERIC</code>,'
2985:             *         <code>DECIMAL</code>, <code>BIT</code>, <code>TINYINT</code>,
2986:             *         <code>SMALLINT</code>, <code>INTEGER</code>, <code>BIGINT</code>,
2987:             *         <code>REAL</code>, <code>DOUBLE</code>, or <code>FLOAT</code>;
2988:             *         <code>false</code> otherwise
2989:             */
2990:            private boolean isNumeric(int type) {
2991:                switch (type) {
2992:                case java.sql.Types.NUMERIC:
2993:                case java.sql.Types.DECIMAL:
2994:                case java.sql.Types.BIT:
2995:                case java.sql.Types.TINYINT:
2996:                case java.sql.Types.SMALLINT:
2997:                case java.sql.Types.INTEGER:
2998:                case java.sql.Types.BIGINT:
2999:                case java.sql.Types.REAL:
3000:                case java.sql.Types.DOUBLE:
3001:                case java.sql.Types.FLOAT:
3002:                    return true;
3003:                default:
3004:                    return false;
3005:                }
3006:            }
3007:
3008:            /**
3009:             * Indicates whether the given SQL data type is a string type.
3010:             *
3011:             * @param type one of the constants from <code>java.sql.Types</code>
3012:             * @return <code>true</code> if the given type is <code>CHAR</code>,'
3013:             *         <code>VARCHAR</code>, or <code>LONGVARCHAR</code>;
3014:             *         <code>false</code> otherwise
3015:             */
3016:            private boolean isString(int type) {
3017:                switch (type) {
3018:                case java.sql.Types.CHAR:
3019:                case java.sql.Types.VARCHAR:
3020:                case java.sql.Types.LONGVARCHAR:
3021:                    return true;
3022:                default:
3023:                    return false;
3024:                }
3025:            }
3026:
3027:            /**
3028:             * Indicates whether the given SQL data type is a binary type.
3029:             *
3030:             * @param type one of the constants from <code>java.sql.Types</code>
3031:             * @return <code>true</code> if the given type is <code>BINARY</code>,'
3032:             *         <code>VARBINARY</code>, or <code>LONGVARBINARY</code>;
3033:             *         <code>false</code> otherwise
3034:             */
3035:            private boolean isBinary(int type) {
3036:                switch (type) {
3037:                case java.sql.Types.BINARY:
3038:                case java.sql.Types.VARBINARY:
3039:                case java.sql.Types.LONGVARBINARY:
3040:                    return true;
3041:                default:
3042:                    return false;
3043:                }
3044:            }
3045:
3046:            /**
3047:             * Indicates whether the given SQL data type is a temporal type.
3048:             * This method is called internally by the conversion methods
3049:             * <code>convertNumeric</code> and <code>convertTemporal</code>.
3050:             *
3051:             * @param type one of the constants from <code>java.sql.Types</code>
3052:             * @return <code>true</code> if the given type is <code>DATE</code>,
3053:             *         <code>TIME</code>, or <code>TIMESTAMP</code>;
3054:             *         <code>false</code> otherwise
3055:             */
3056:            private boolean isTemporal(int type) {
3057:                switch (type) {
3058:                case java.sql.Types.DATE:
3059:                case java.sql.Types.TIME:
3060:                case java.sql.Types.TIMESTAMP:
3061:                    return true;
3062:                default:
3063:                    return false;
3064:                }
3065:            }
3066:
3067:            /**
3068:             * Converts the given <code>Object</code> in the Java programming language
3069:             * to the standard mapping for the specified SQL target data type.
3070:             * The conversion must be to a string or numeric type, but there are no
3071:             * restrictions on the type to be converted.  If the source type and target
3072:             * type are the same, the given object is simply returned.
3073:             *
3074:             * @param srcObj the <code>Object</code> in the Java programming language
3075:             *               that is to be converted to the target type
3076:             * @param srcType the data type that is the standard mapping in SQL of the
3077:             *                object to be converted; must be one of the constants in
3078:             *                <code>java.sql.Types</code>
3079:             * @param trgType the SQL data type to which to convert the given object;
3080:             *                must be one of the following constants in
3081:             *                <code>java.sql.Types</code>: <code>NUMERIC</code>,
3082:             *         <code>DECIMAL</code>, <code>BIT</code>, <code>TINYINT</code>,
3083:             *         <code>SMALLINT</code>, <code>INTEGER</code>, <code>BIGINT</code>,
3084:             *         <code>REAL</code>, <code>DOUBLE</code>, <code>FLOAT</code>,
3085:             *         <code>VARCHAR</code>, <code>LONGVARCHAR</code>, or <code>CHAR</code>
3086:             * @return an <code>Object</code> value.that is
3087:             *         the standard object mapping for the target SQL type
3088:             * @throws SQLException if the given target type is not one of the string or
3089:             *         numeric types in <code>java.sql.Types</code>
3090:             */
3091:            private Object convertNumeric(Object srcObj, int srcType,
3092:                    int trgType) throws SQLException {
3093:
3094:                if (srcType == trgType) {
3095:                    return srcObj;
3096:                }
3097:
3098:                if (isNumeric(trgType) == false && isString(trgType) == false) {
3099:                    throw new SQLException(rb.getString("DATATYPE_MISMATCH")
3100:                            + trgType); //NOI18N
3101:                }
3102:
3103:                try {
3104:                    switch (trgType) {
3105:                    case java.sql.Types.BIT:
3106:                        Integer i = new Integer(srcObj.toString().trim());
3107:                        return i.equals(new Integer((int) 0)) ? new Boolean(
3108:                                false) : new Boolean(true);
3109:                    case java.sql.Types.TINYINT:
3110:                        return new Byte(srcObj.toString().trim());
3111:                    case java.sql.Types.SMALLINT:
3112:                        return new Short(srcObj.toString().trim());
3113:                    case java.sql.Types.INTEGER:
3114:                        return new Integer(srcObj.toString().trim());
3115:                    case java.sql.Types.BIGINT:
3116:                        return new Long(srcObj.toString().trim());
3117:                    case java.sql.Types.NUMERIC:
3118:                    case java.sql.Types.DECIMAL:
3119:                        return new BigDecimal(srcObj.toString().trim());
3120:                    case java.sql.Types.REAL:
3121:                    case java.sql.Types.FLOAT:
3122:                        return new Float(srcObj.toString().trim());
3123:                    case java.sql.Types.DOUBLE:
3124:                        return new Double(srcObj.toString().trim());
3125:                    case java.sql.Types.CHAR:
3126:                    case java.sql.Types.VARCHAR:
3127:                    case java.sql.Types.LONGVARCHAR:
3128:                        return new String(srcObj.toString());
3129:                    default:
3130:                        throw new SQLException(rb
3131:                                .getString("DATATYPE_MISMATCH")
3132:                                + trgType); //NOI18N
3133:                    }
3134:                } catch (NumberFormatException ex) {
3135:                    throw new SQLException(rb.getString("DATATYPE_MISMATCH")
3136:                            + trgType); //NOI18N
3137:                }
3138:            }
3139:
3140:            /**
3141:             * Converts the given <code>Object</code> in the Java programming language
3142:             * to the standard object mapping for the specified SQL target data type.
3143:             * The conversion must be to a string or temporal type, and there are also
3144:             * restrictions on the type to be converted.
3145:             * <P>
3146:             * <TABLE ALIGN="CENTER" BORDER CELLPADDING=10 BORDERCOLOR="#0000FF"
3147:             * <CAPTION ALIGN="CENTER"><B>Parameters and Return Values</B></CAPTION>
3148:             * <TR>
3149:             *   <TD><B>Source SQL Type</B>
3150:             *   <TD><B>Target SQL Type</B>
3151:             *   <TD><B>Object Returned</B>
3152:             * </TR>
3153:             * <TR>
3154:             *   <TD><code>TIMESTAMP</code>
3155:             *   <TD><code>DATE</code>
3156:             *   <TD><code>java.sql.Date</code>
3157:             * </TR>
3158:             * <TR>
3159:             *   <TD><code>TIMESTAMP</code>
3160:             *   <TD><code>TIME</code>
3161:             *   <TD><code>java.sql.Time</code>
3162:             * </TR>
3163:             * <TR>
3164:             *   <TD><code>TIME</code>
3165:             *   <TD><code>TIMESTAMP</code>
3166:             *   <TD><code>java.sql.Timestamp</code>
3167:             * </TR>
3168:             * <TR>
3169:             *   <TD><code>DATE</code>, <code>TIME</code>, or <code>TIMESTAMP</code>
3170:             *   <TD><code>CHAR</code>, <code>VARCHAR</code>, or <code>LONGVARCHAR</code>
3171:             *   <TD><code>java.lang.String</code>
3172:             * </TR>
3173:             * </TABLE>
3174:             * <P>
3175:             * If the source type and target type are the same,
3176:             * the given object is simply returned.
3177:             *
3178:             * @param srcObj the <code>Object</code> in the Java programming language
3179:             *               that is to be converted to the target type
3180:             * @param srcType the data type that is the standard mapping in SQL of the
3181:             *                object to be converted; must be one of the constants in
3182:             *                <code>java.sql.Types</code>
3183:             * @param trgType the SQL data type to which to convert the given object;
3184:             *                must be one of the following constants in
3185:             *                <code>java.sql.Types</code>: <code>DATE</code>,
3186:             *         <code>TIME</code>, <code>TIMESTAMP</code>, <code>CHAR</code>,
3187:             *         <code>VARCHAR</code>, or <code>LONGVARCHAR</code>
3188:             * @return an <code>Object</code> value.that is
3189:             *         the standard object mapping for the target SQL type
3190:             * @throws SQLException if the given target type is not one of the string or
3191:             *         temporal types in <code>java.sql.Types</code>
3192:             */
3193:            private Object convertTemporal(Object srcObj, int srcType,
3194:                    int trgType) throws SQLException {
3195:
3196:                if (srcType == trgType) {
3197:                    return srcObj;
3198:                }
3199:
3200:                if (isNumeric(trgType) == true
3201:                        || (isString(trgType) == false && isTemporal(trgType) == false)) {
3202:                    throw new SQLException(rb.getString("DATATYPE_MISMATCH")
3203:                            + trgType); //NOI18N
3204:                }
3205:
3206:                try {
3207:                    switch (trgType) {
3208:                    case java.sql.Types.DATE:
3209:                        if (srcType == java.sql.Types.TIMESTAMP) {
3210:                            return new java.sql.Date(
3211:                                    ((java.sql.Timestamp) srcObj).getTime());
3212:                        } else {
3213:                            throw new SQLException(rb
3214:                                    .getString("DATATYPE_MISMATCH")); //NOI18N
3215:                        }
3216:                    case java.sql.Types.TIMESTAMP:
3217:                        if (srcType == java.sql.Types.TIME) {
3218:                            return new Timestamp(((java.sql.Time) srcObj)
3219:                                    .getTime());
3220:                        } else {
3221:                            return new Timestamp(((java.sql.Date) srcObj)
3222:                                    .getTime());
3223:                        }
3224:                    case java.sql.Types.TIME:
3225:                        if (srcType == java.sql.Types.TIMESTAMP) {
3226:                            return new Time(((java.sql.Timestamp) srcObj)
3227:                                    .getTime());
3228:                        } else {
3229:                            throw new SQLException(rb
3230:                                    .getString("DATATYPE_MISMATCH")); //NOI18N
3231:                        }
3232:                    case java.sql.Types.CHAR:
3233:                    case java.sql.Types.VARCHAR:
3234:                    case java.sql.Types.LONGVARCHAR:
3235:                        return new String(srcObj.toString());
3236:                    default:
3237:                        throw new SQLException(rb
3238:                                .getString("DATATYPE_MISMATCH")); //NOI18N
3239:                    }
3240:                } catch (NumberFormatException ex) {
3241:                    throw new SQLException(rb.getString("DATATYPE_MISMATCH")); //NOI18N
3242:                }
3243:
3244:            }
3245:
3246:            /**
3247:             * {@inheritDoc}
3248:             */
3249:            public void updateNull(int columnIndex) throws SQLException {
3250:                checkExecuted();
3251:                // sanity check.
3252:                checkIndex(columnIndex);
3253:                // make sure the cursor is on a valid row
3254:                checkCursor();
3255:
3256:                BaseRow row = getCurrentRow();
3257:                row.setColumnObject(columnIndex, null);
3258:            }
3259:
3260:            /**
3261:             * {@inheritDoc}
3262:             */
3263:            public void updateBoolean(int columnIndex, boolean x)
3264:                    throws SQLException {
3265:                checkExecuted();
3266:                // sanity check.
3267:                checkIndex(columnIndex);
3268:                // make sure the cursor is on a valid row
3269:                checkCursor();
3270:                Object obj = convertNumeric(new Boolean(x), java.sql.Types.BIT,
3271:                        rowSetMD.getColumnType(columnIndex));
3272:
3273:                getCurrentRow().setColumnObject(columnIndex, obj);
3274:            }
3275:
3276:            /**
3277:             * {@inheritDoc}
3278:             */
3279:            public void updateByte(int columnIndex, byte x) throws SQLException {
3280:                checkExecuted();
3281:                // sanity check.
3282:                checkIndex(columnIndex);
3283:                // make sure the cursor is on a valid row
3284:                checkCursor();
3285:
3286:                Object obj = convertNumeric(new Byte(x),
3287:                        java.sql.Types.TINYINT, rowSetMD
3288:                                .getColumnType(columnIndex));
3289:
3290:                getCurrentRow().setColumnObject(columnIndex, obj);
3291:            }
3292:
3293:            /**
3294:             * {@inheritDoc}
3295:             */
3296:            public void updateShort(int columnIndex, short x)
3297:                    throws SQLException {
3298:                checkExecuted();
3299:                // sanity check.
3300:                checkIndex(columnIndex);
3301:                // make sure the cursor is on a valid row
3302:                checkCursor();
3303:
3304:                Object obj = convertNumeric(new Short(x),
3305:                        java.sql.Types.SMALLINT, rowSetMD
3306:                                .getColumnType(columnIndex));
3307:
3308:                getCurrentRow().setColumnObject(columnIndex, obj);
3309:            }
3310:
3311:            /**
3312:             * {@inheritDoc}
3313:             */
3314:            public void updateInt(int columnIndex, int x) throws SQLException {
3315:                checkExecuted();
3316:                // sanity check.
3317:                checkIndex(columnIndex);
3318:                // make sure the cursor is on a valid row
3319:                checkCursor();
3320:                Object obj = convertNumeric(new Integer(x),
3321:                        java.sql.Types.INTEGER, rowSetMD
3322:                                .getColumnType(columnIndex));
3323:
3324:                getCurrentRow().setColumnObject(columnIndex, obj);
3325:            }
3326:
3327:            /**
3328:             * {@inheritDoc}
3329:             */
3330:            public void updateLong(int columnIndex, long x) throws SQLException {
3331:                checkExecuted();
3332:                // sanity check.
3333:                checkIndex(columnIndex);
3334:                // make sure the cursor is on a valid row
3335:                checkCursor();
3336:
3337:                Object obj = convertNumeric(new Long(x), java.sql.Types.BIGINT,
3338:                        rowSetMD.getColumnType(columnIndex));
3339:
3340:                getCurrentRow().setColumnObject(columnIndex, obj);
3341:
3342:            }
3343:
3344:            /**
3345:             * {@inheritDoc}
3346:             */
3347:            public void updateFloat(int columnIndex, float x)
3348:                    throws SQLException {
3349:                checkExecuted();
3350:                // sanity check.
3351:                checkIndex(columnIndex);
3352:                // make sure the cursor is on a valid row
3353:                checkCursor();
3354:
3355:                Object obj = convertNumeric(new Float(x), java.sql.Types.REAL,
3356:                        rowSetMD.getColumnType(columnIndex));
3357:
3358:                getCurrentRow().setColumnObject(columnIndex, obj);
3359:            }
3360:
3361:            /**
3362:             * {@inheritDoc}
3363:             */
3364:            public void updateDouble(int columnIndex, double x)
3365:                    throws SQLException {
3366:                checkExecuted();
3367:                // sanity check.
3368:                checkIndex(columnIndex);
3369:                // make sure the cursor is on a valid row
3370:                checkCursor();
3371:                Object obj = convertNumeric(new Double(x),
3372:                        java.sql.Types.DOUBLE, rowSetMD
3373:                                .getColumnType(columnIndex));
3374:
3375:                getCurrentRow().setColumnObject(columnIndex, obj);
3376:            }
3377:
3378:            /**
3379:             * {@inheritDoc}
3380:             */
3381:            public void updateBigDecimal(int columnIndex, BigDecimal x)
3382:                    throws SQLException {
3383:                checkExecuted();
3384:                // sanity check.
3385:                checkIndex(columnIndex);
3386:                // make sure the cursor is on a valid row
3387:                checkCursor();
3388:
3389:                Object obj = convertNumeric(x, java.sql.Types.NUMERIC, rowSetMD
3390:                        .getColumnType(columnIndex));
3391:
3392:                getCurrentRow().setColumnObject(columnIndex, obj);
3393:            }
3394:
3395:            /**
3396:             * {@inheritDoc}
3397:             */
3398:            public void updateString(int columnIndex, String x)
3399:                    throws SQLException {
3400:                checkExecuted();
3401:                // sanity check.
3402:                checkIndex(columnIndex);
3403:                // make sure the cursor is on a valid row
3404:                checkCursor();
3405:
3406:                getCurrentRow().setColumnObject(columnIndex, x);
3407:            }
3408:
3409:            /**
3410:             * {@inheritDoc}
3411:             */
3412:            public void updateBytes(int columnIndex, byte x[])
3413:                    throws SQLException {
3414:                checkExecuted();
3415:                // sanity check.
3416:                checkIndex(columnIndex);
3417:                // make sure the cursor is on a valid row
3418:                checkCursor();
3419:
3420:                if (isBinary(rowSetMD.getColumnType(columnIndex)) == false) {
3421:                    throw new SQLException(rb.getString("DATATYPE_MISMATCH")); //NOI18N
3422:                }
3423:
3424:                getCurrentRow().setColumnObject(columnIndex, x);
3425:            }
3426:
3427:            /**
3428:             * {@inheritDoc}
3429:             */
3430:            public void updateDate(int columnIndex, java.sql.Date x)
3431:                    throws SQLException {
3432:                checkExecuted();
3433:                // sanity check.
3434:                checkIndex(columnIndex);
3435:                // make sure the cursor is on a valid row
3436:                checkCursor();
3437:
3438:                Object obj = convertTemporal(x, java.sql.Types.DATE, rowSetMD
3439:                        .getColumnType(columnIndex));
3440:
3441:                getCurrentRow().setColumnObject(columnIndex, obj);
3442:            }
3443:
3444:            /**
3445:             * {@inheritDoc}
3446:             */
3447:            public void updateTime(int columnIndex, java.sql.Time x)
3448:                    throws SQLException {
3449:                checkExecuted();
3450:                // sanity check.
3451:                checkIndex(columnIndex);
3452:                // make sure the cursor is on a valid row
3453:                checkCursor();
3454:
3455:                Object obj = convertTemporal(x, java.sql.Types.TIME, rowSetMD
3456:                        .getColumnType(columnIndex));
3457:
3458:                getCurrentRow().setColumnObject(columnIndex, obj);
3459:            }
3460:
3461:            /**
3462:             * {@inheritDoc}
3463:             */
3464:            public void updateTimestamp(int columnIndex, java.sql.Timestamp x)
3465:                    throws SQLException {
3466:                checkExecuted();
3467:                // sanity check.
3468:                checkIndex(columnIndex);
3469:                // make sure the cursor is on a valid row
3470:                checkCursor();
3471:
3472:                Object obj = convertTemporal(x, java.sql.Types.TIMESTAMP,
3473:                        rowSetMD.getColumnType(columnIndex));
3474:
3475:                getCurrentRow().setColumnObject(columnIndex, obj);
3476:            }
3477:
3478:            /**
3479:             * {@inheritDoc}
3480:             */
3481:            public void updateAsciiStream(int columnIndex,
3482:                    java.io.InputStream x, int length) throws SQLException {
3483:                checkExecuted();
3484:                // sanity Check
3485:                checkIndex(columnIndex);
3486:                // make sure the cursor is on a valid row
3487:                checkCursor();
3488:
3489:                if (isString(rowSetMD.getColumnType(columnIndex)) == false
3490:                        && isBinary(rowSetMD.getColumnType(columnIndex)) == false) {
3491:                    throw new SQLException(rb.getString("DATATYPE_MISMATCH")); //NOI18N
3492:                }
3493:
3494:                byte buf[] = new byte[length];
3495:                try {
3496:                    int charsRead = 0;
3497:                    do {
3498:                        charsRead += x.read(buf, charsRead, length - charsRead);
3499:                    } while (charsRead != length);
3500:                    //Changed the condition check to check for length instead of -1
3501:                } catch (java.io.IOException ex) {
3502:                    throw new SQLException(rb
3503:                            .getString("READ_FAILED_ASCII_STREAM")); //NOI18N
3504:                }
3505:                String str = new String(buf);
3506:
3507:                getCurrentRow().setColumnObject(columnIndex, str);
3508:
3509:            }
3510:
3511:            /**
3512:             * {@inheritDoc}
3513:             */
3514:            public void updateBinaryStream(int columnIndex,
3515:                    java.io.InputStream x, int length) throws SQLException {
3516:                checkExecuted();
3517:                // sanity Check
3518:                checkIndex(columnIndex);
3519:                // make sure the cursor is on a valid row
3520:                checkCursor();
3521:
3522:                if (isBinary(rowSetMD.getColumnType(columnIndex)) == false) {
3523:                    throw new SQLException(rb.getString("DATATYPE_MISMATCH")); //NOI18N
3524:                }
3525:
3526:                byte buf[] = new byte[length];
3527:                try {
3528:                    int bytesRead = 0;
3529:                    do {
3530:                        bytesRead += x.read(buf, bytesRead, length - bytesRead);
3531:                    } while (bytesRead != -1);
3532:                } catch (java.io.IOException ex) {
3533:                    throw new SQLException(rb
3534:                            .getString("READ_FAILED_BINARY_STREAM")); //NOI18N
3535:                }
3536:
3537:                getCurrentRow().setColumnObject(columnIndex, buf);
3538:            }
3539:
3540:            /**
3541:             * {@inheritDoc}
3542:             */
3543:            public void updateCharacterStream(int columnIndex,
3544:                    java.io.Reader x, int length) throws SQLException {
3545:                checkExecuted();
3546:                // sanity Check
3547:                checkIndex(columnIndex);
3548:                // make sure the cursor is on a valid row
3549:                checkCursor();
3550:
3551:                if (isString(rowSetMD.getColumnType(columnIndex)) == false
3552:                        && isBinary(rowSetMD.getColumnType(columnIndex)) == false) {
3553:                    throw new SQLException(rb.getString("DATATYPE_MISMATCH")); //NOI18N
3554:                }
3555:
3556:                char buf[] = new char[length];
3557:                try {
3558:                    int charsRead = 0;
3559:                    do {
3560:                        charsRead += x.read(buf, charsRead, length - charsRead);
3561:                    } while (charsRead != length);
3562:                    //Changed the condition checking to check for length instead of -1
3563:                } catch (java.io.IOException ex) {
3564:                    throw new SQLException(rb
3565:                            .getString("READ_FAILED_BINARY_STREAM")); //NOI18N
3566:                }
3567:                String str = new String(buf);
3568:
3569:                getCurrentRow().setColumnObject(columnIndex, str);
3570:            }
3571:
3572:            /**
3573:             * {@inheritDoc}
3574:             */
3575:            public void updateObject(int columnIndex, Object x, int scale)
3576:                    throws SQLException {
3577:                checkExecuted();
3578:                // sanity check.
3579:                checkIndex(columnIndex);
3580:                // make sure the cursor is on a valid row
3581:                checkCursor();
3582:
3583:                int type = rowSetMD.getColumnType(columnIndex);
3584:                if (type == Types.DECIMAL || type == Types.NUMERIC) {
3585:                    ((java.math.BigDecimal) x).setScale(scale);
3586:                }
3587:                getCurrentRow().setColumnObject(columnIndex, x);
3588:            }
3589:
3590:            /**
3591:             * {@inheritDoc}
3592:             */
3593:            public void updateObject(int columnIndex, Object x)
3594:                    throws SQLException {
3595:                checkExecuted();
3596:                // sanity check.
3597:                checkIndex(columnIndex);
3598:                // make sure the cursor is on a valid row
3599:                checkCursor();
3600:
3601:                getCurrentRow().setColumnObject(columnIndex, x);
3602:            }
3603:
3604:            /**
3605:             * {@inheritDoc}
3606:             */
3607:            public void updateNull(String columnName) throws SQLException {
3608:                checkExecuted();
3609:                updateNull(getColIdxByName(columnName));
3610:            }
3611:
3612:            /**
3613:             * {@inheritDoc}
3614:             */
3615:            public void updateBoolean(String columnName, boolean x)
3616:                    throws SQLException {
3617:                checkExecuted();
3618:                updateBoolean(getColIdxByName(columnName), x);
3619:            }
3620:
3621:            public void updateByte(String columnName, byte x)
3622:                    throws SQLException {
3623:                checkExecuted();
3624:                updateByte(getColIdxByName(columnName), x);
3625:            }
3626:
3627:            public void updateShort(String columnName, short x)
3628:                    throws SQLException {
3629:                checkExecuted();
3630:                updateShort(getColIdxByName(columnName), x);
3631:            }
3632:
3633:            public void updateInt(String columnName, int x) throws SQLException {
3634:                checkExecuted();
3635:                updateInt(getColIdxByName(columnName), x);
3636:            }
3637:
3638:            public void updateLong(String columnName, long x)
3639:                    throws SQLException {
3640:                checkExecuted();
3641:                updateLong(getColIdxByName(columnName), x);
3642:            }
3643:
3644:            public void updateFloat(String columnName, float x)
3645:                    throws SQLException {
3646:                checkExecuted();
3647:                updateFloat(getColIdxByName(columnName), x);
3648:            }
3649:
3650:            public void updateDouble(String columnName, double x)
3651:                    throws SQLException {
3652:                checkExecuted();
3653:                updateDouble(getColIdxByName(columnName), x);
3654:            }
3655:
3656:            public void updateBigDecimal(String columnName, BigDecimal x)
3657:                    throws SQLException {
3658:                checkExecuted();
3659:                updateBigDecimal(getColIdxByName(columnName), x);
3660:            }
3661:
3662:            public void updateString(String columnName, String x)
3663:                    throws SQLException {
3664:                checkExecuted();
3665:                updateString(getColIdxByName(columnName), x);
3666:            }
3667:
3668:            public void updateBytes(String columnName, byte x[])
3669:                    throws SQLException {
3670:                checkExecuted();
3671:                updateBytes(getColIdxByName(columnName), x);
3672:            }
3673:
3674:            public void updateDate(String columnName, java.sql.Date x)
3675:                    throws SQLException {
3676:                checkExecuted();
3677:                updateDate(getColIdxByName(columnName), x);
3678:            }
3679:
3680:            public void updateTime(String columnName, java.sql.Time x)
3681:                    throws SQLException {
3682:                checkExecuted();
3683:                updateTime(getColIdxByName(columnName), x);
3684:            }
3685:
3686:            public void updateTimestamp(String columnName, java.sql.Timestamp x)
3687:                    throws SQLException {
3688:                checkExecuted();
3689:                updateTimestamp(getColIdxByName(columnName), x);
3690:            }
3691:
3692:            public void updateAsciiStream(String columnName,
3693:                    java.io.InputStream x, int length) throws SQLException {
3694:                checkExecuted();
3695:                updateAsciiStream(getColIdxByName(columnName), x, length);
3696:            }
3697:
3698:            public void updateBinaryStream(String columnName,
3699:                    java.io.InputStream x, int length) throws SQLException {
3700:                checkExecuted();
3701:                updateBinaryStream(getColIdxByName(columnName), x, length);
3702:            }
3703:
3704:            public void updateCharacterStream(String columnName,
3705:                    java.io.Reader reader, int length) throws SQLException {
3706:                checkExecuted();
3707:                updateCharacterStream(getColIdxByName(columnName), reader,
3708:                        length);
3709:            }
3710:
3711:            public void updateObject(String columnName, Object x, int scale)
3712:                    throws SQLException {
3713:                checkExecuted();
3714:                updateObject(getColIdxByName(columnName), x, scale);
3715:            }
3716:
3717:            public void updateObject(String columnName, Object x)
3718:                    throws SQLException {
3719:                checkExecuted();
3720:                updateObject(getColIdxByName(columnName), x);
3721:            }
3722:
3723:            public void insertRow() throws SQLException {
3724:                checkExecuted();
3725:                int pos;
3726:
3727:                if (onInsertRow == false) {
3728:                    throw new SQLException(rb.getString("INSERT_ROW_FAILED")); //NOI18N
3729:                }
3730:                /* We cannot reliably compute whether or not this is a complete row without
3731:                 * obtaining a connection to see what is and isn't an insertable column.  For
3732:                 * now, we will relax this requirement.  In the future, perhaps we will obtain this
3733:                 * information when the rowset is populated -- and then hand it off to the writer
3734:                 * (which is currently computing this type of information.
3735:                 *
3736:                if (insertRow.isCompleteRow(rowSetMD) == false) {
3737:                    throw new SQLException(rb.getString("INSERT_ROW_FAILED")); //NOI18N
3738:                }
3739:                 */
3740:                // Added the setting of parameters that are passed
3741:                // to setXXX methods after an empty CRS Object is
3742:                // created through RowSetMetaData object
3743:                // removed what came from the RI version - bug 6345804
3744:                Row insRow = new Row(rowSetMD.getColumnCount(), insertRow
3745:                        .getOrigRow());
3746:                insRow.setInserted();
3747:                /*
3748:                 * The new row is inserted into the RowSet
3749:                 * immediately following the current row.
3750:                 *
3751:                 * If we are afterlast then the rows are
3752:                 * inserted at the end.
3753:                 */
3754:                if (currentRow >= numRows || currentRow < 0) {
3755:                    pos = numRows;
3756:                } else {
3757:                    pos = currentRow;
3758:                }
3759:
3760:                rvh.add(pos, insRow);
3761:                ++numRows;
3762:                onInsertRow = false;
3763:                cursorPos = currentRow; /*!JK: aded this */
3764:                // notify the listeners that the row changed.
3765:                notifyRowChanged();
3766:            }
3767:
3768:            public void updateRow() throws SQLException {
3769:                checkExecuted();
3770:                // make sure we aren't on the insert row
3771:                if (onInsertRow == true) {
3772:                    throw new SQLException(rb
3773:                            .getString("UPDATE_ROW_CALLED_ON_INSERT_ROW")); //NOI18N
3774:                }
3775:
3776:                ((Row) getCurrentRow()).setUpdated();
3777:
3778:                // notify the listeners that the row changed.
3779:                notifyRowChanged();
3780:            }
3781:
3782:            public void deleteRow() throws SQLException {
3783:                checkExecuted();
3784:                // make sure the cursor is on a valid row
3785:                checkCursor();
3786:
3787:                ((Row) getCurrentRow()).setDeleted();
3788:                ++numDeleted;
3789:
3790:                // notify the listeners that the row changed.
3791:                notifyRowChanged();
3792:            }
3793:
3794:            public void refreshRow() throws SQLException {
3795:                checkExecuted();
3796:                // make sure we are on a row
3797:                checkCursor();
3798:
3799:                // don't want this to happen...
3800:                if (onInsertRow == true) {
3801:                    throw new SQLException(rb.getString("INVALID_CURSOR_POS")); //NOI18N
3802:                }
3803:
3804:                Row currentRow = (Row) getCurrentRow();
3805:                // just undo any changes made to this row.
3806:                currentRow.clearUpdated();
3807:
3808:            }
3809:
3810:            public void cancelRowUpdates() throws SQLException {
3811:                checkExecuted();
3812:                // make sure we are on a row
3813:                checkCursor();
3814:
3815:                // don't want this to happen...
3816:                if (onInsertRow == true) {
3817:                    throw new SQLException(rb.getString("INVALID_CURSOR_POS")); //NOI18N
3818:                }
3819:
3820:                Row currentRow = (Row) getCurrentRow();
3821:                if (currentRow.getUpdated() == true) {
3822:                    currentRow.clearUpdated();
3823:                    notifyRowChanged();
3824:                }
3825:            }
3826:
3827:            public void moveToInsertRow() throws SQLException {
3828:                checkExecuted();
3829:                if (getConcurrency() == ResultSet.CONCUR_READ_ONLY) {
3830:                    throw new SQLException(rb
3831:                            .getString("RESULTSET_IS_READONLY")); //NOI18N
3832:                }
3833:                if (insertRow == null) {
3834:                    if (rowSetMD == null)
3835:                        throw new SQLException(rb
3836:                                .getString("MOVE_TO_INSERT_ROW_NO_MD")); //NOI18N
3837:                    int numCols = rowSetMD.getColumnCount();
3838:                    if (numCols > 0) {
3839:                        insertRow = new InsertRow(numCols);
3840:                    } else {
3841:                        throw new SQLException(
3842:                                rb
3843:                                        .getString("MOVE_TO_INSERT_ROW_INVALID_NO_OF_COLS")); //NOI18N
3844:                    }
3845:                }
3846:                onInsertRow = true;
3847:                // %%% setCurrentRow called in BaseRow
3848:
3849:                currentRow = cursorPos;
3850:                cursorPos = -1;
3851:
3852:                insertRow.initInsertRow();
3853:            }
3854:
3855:            public void moveToCurrentRow() throws SQLException {
3856:                checkExecuted();
3857:                if (onInsertRow == false) {
3858:                    return;
3859:                } else {
3860:                    cursorPos = currentRow;
3861:                    onInsertRow = false;
3862:                }
3863:            }
3864:
3865:            /**
3866:             * Returns <code>null</code>.
3867:             *
3868:             * @return <code>null</code>
3869:             * @throws SQLException if an error occurs
3870:             */
3871:            public Statement getStatement() throws SQLException {
3872:                return null;
3873:            }
3874:
3875:            public Object getObject(int columnIndex, java.util.Map map)
3876:                    throws SQLException {
3877:                checkExecuted();
3878:                Object value;
3879:
3880:                // sanity check.
3881:                checkIndex(columnIndex);
3882:                // make sure the cursor is on a valid row
3883:                checkCursor();
3884:
3885:                setLastValueNull(false);
3886:                value = getCurrentRow().getColumnObject(columnIndex);
3887:
3888:                // check for SQL NULL
3889:                if (value == null) {
3890:                    setLastValueNull(true);
3891:                    return null;
3892:                }
3893:                if (value instanceof  Struct) {
3894:                    Struct s = (Struct) value;
3895:
3896:                    // look up the class in the map
3897:                    Class c = (Class) map.get(s.getSQLTypeName());
3898:                    if (c != null) {
3899:                        // create new instance of the class
3900:                        SQLData obj = null;
3901:                        try {
3902:                            obj = (SQLData) c.newInstance();
3903:                        } catch (java.lang.InstantiationException ex) {
3904:                            throw new SQLException(rb
3905:                                    .getString("UNABLE_TO_INSTANTIATE")
3906:                                    + ex.getMessage()); //NOI18N
3907:                        } catch (java.lang.IllegalAccessException ex) {
3908:                            throw new SQLException(rb
3909:                                    .getString("UNABLE_TO_INSTANTIATE")
3910:                                    + ex.getMessage()); //NOI18N
3911:                        }
3912:                        // get the attributes from the struct
3913:                        Object attribs[] = s.getAttributes(map);
3914:                        // create the SQLInput "stream"
3915:                        SQLInputImpl sqlInput = new SQLInputImpl(attribs, map);
3916:                        // read the values...
3917:                        obj.readSQL(sqlInput, s.getSQLTypeName());
3918:                        return (Object) obj;
3919:                    }
3920:                }
3921:                return value;
3922:            }
3923:
3924:            public Ref getRef(int columnIndex) throws SQLException {
3925:                checkExecuted();
3926:                Ref value;
3927:
3928:                // sanity check.
3929:                checkIndex(columnIndex);
3930:                // make sure the cursor is on a valid row
3931:                checkCursor();
3932:
3933:                if (rowSetMD.getColumnType(columnIndex) != java.sql.Types.REF) {
3934:                    throw new SQLException(rb.getString("DATATYPE_MISMATCH")); //NOI18N
3935:                }
3936:
3937:                setLastValueNull(false);
3938:                value = (Ref) (getCurrentRow().getColumnObject(columnIndex));
3939:
3940:                // check for SQL NULL
3941:                if (value == null) {
3942:                    setLastValueNull(true);
3943:                    return null;
3944:                }
3945:
3946:                return value;
3947:            }
3948:
3949:            public Blob getBlob(int columnIndex) throws SQLException {
3950:                checkExecuted();
3951:                Blob value;
3952:
3953:                // sanity check.
3954:                checkIndex(columnIndex);
3955:                // make sure the cursor is on a valid row
3956:                checkCursor();
3957:
3958:                if (rowSetMD.getColumnType(columnIndex) != java.sql.Types.BLOB) {
3959:                    //System.out.println("Type is: "+rowSetMD.getColumnType(columnIndex));
3960:                    throw new SQLException(rb.getString("DATATYPE_MISMATCH")); //NOI18N
3961:                }
3962:
3963:                setLastValueNull(false);
3964:                value = (Blob) (getCurrentRow().getColumnObject(columnIndex));
3965:
3966:                // check for SQL NULL
3967:                if (value == null) {
3968:                    setLastValueNull(true);
3969:                    return null;
3970:                }
3971:
3972:                return value;
3973:            }
3974:
3975:            public Clob getClob(int columnIndex) throws SQLException {
3976:                checkExecuted();
3977:                Clob value;
3978:
3979:                // sanity check.
3980:                checkIndex(columnIndex);
3981:                // make sure the cursor is on a valid row
3982:                checkCursor();
3983:
3984:                if (rowSetMD.getColumnType(columnIndex) != java.sql.Types.CLOB) {
3985:                    //System.out.println("Type is: "+rowSetMD.getColumnType(columnIndex));
3986:                    throw new SQLException(rb.getString("DATATYPE_MISMATCH")); //NOI18N
3987:                }
3988:
3989:                setLastValueNull(false);
3990:                value = (Clob) (getCurrentRow().getColumnObject(columnIndex));
3991:
3992:                // check for SQL NULL
3993:                if (value == null) {
3994:                    setLastValueNull(true);
3995:                    return null;
3996:                }
3997:
3998:                return value;
3999:            }
4000:
4001:            public Array getArray(int columnIndex) throws SQLException {
4002:                checkExecuted();
4003:                java.sql.Array value;
4004:
4005:                // sanity check.
4006:                checkIndex(columnIndex);
4007:                // make sure the cursor is on a valid row
4008:                checkCursor();
4009:
4010:                if (rowSetMD.getColumnType(columnIndex) != java.sql.Types.ARRAY) {
4011:                    throw new SQLException(rb.getString("DATATYPE_MISMATCH")); //NOI18N
4012:                }
4013:
4014:                setLastValueNull(false);
4015:                value = (java.sql.Array) (getCurrentRow()
4016:                        .getColumnObject(columnIndex));
4017:
4018:                // check for SQL NULL
4019:                if (value == null) {
4020:                    setLastValueNull(true);
4021:                    return null;
4022:                }
4023:
4024:                return value;
4025:            }
4026:
4027:            public Object getObject(String columnName, java.util.Map map)
4028:                    throws SQLException {
4029:                checkExecuted();
4030:                return getObject(getColIdxByName(columnName), map);
4031:            }
4032:
4033:            public Ref getRef(String colName) throws SQLException {
4034:                checkExecuted();
4035:                return getRef(getColIdxByName(colName));
4036:            }
4037:
4038:            public Blob getBlob(String colName) throws SQLException {
4039:                checkExecuted();
4040:                return getBlob(getColIdxByName(colName));
4041:            }
4042:
4043:            public Clob getClob(String colName) throws SQLException {
4044:                checkExecuted();
4045:                return getClob(getColIdxByName(colName));
4046:            }
4047:
4048:            public Array getArray(String colName) throws SQLException {
4049:                checkExecuted();
4050:                return getArray(getColIdxByName(colName));
4051:            }
4052:
4053:            public java.sql.Date getDate(int columnIndex, Calendar cal)
4054:                    throws SQLException {
4055:                checkExecuted();
4056:                Object value;
4057:
4058:                // sanity check.
4059:                checkIndex(columnIndex);
4060:                // make sure the cursor is on a valid row
4061:                checkCursor();
4062:
4063:                setLastValueNull(false);
4064:                value = getCurrentRow().getColumnObject(columnIndex);
4065:
4066:                // check for SQL NULL
4067:                if (value == null) {
4068:                    setLastValueNull(true);
4069:                    return null;
4070:                }
4071:
4072:                value = convertTemporal(value, rowSetMD
4073:                        .getColumnType(columnIndex), java.sql.Types.DATE);
4074:
4075:                // create a default calendar
4076:                Calendar defaultCal = Calendar.getInstance();
4077:                // set this Calendar to the time we have
4078:                defaultCal.setTime((java.util.Date) value);
4079:
4080:                /*
4081:                 * Now we can pull the pieces of the date out
4082:                 * of the default calendar and put them into
4083:                 * the user provided calendar
4084:                 */
4085:                cal.set(Calendar.YEAR, defaultCal.get(Calendar.YEAR));
4086:                cal.set(Calendar.MONTH, defaultCal.get(Calendar.MONTH));
4087:                cal.set(Calendar.DAY_OF_MONTH, defaultCal
4088:                        .get(Calendar.DAY_OF_MONTH));
4089:
4090:                /*
4091:                 * This looks a little odd but it is correct -
4092:                 * Calendar.getTime() returns a Date...
4093:                 */
4094:                return new java.sql.Date(cal.getTime().getTime());
4095:            }
4096:
4097:            public java.sql.Date getDate(String columnName, Calendar cal)
4098:                    throws SQLException {
4099:                checkExecuted();
4100:                return getDate(getColIdxByName(columnName), cal);
4101:            }
4102:
4103:            public java.sql.Time getTime(int columnIndex, Calendar cal)
4104:                    throws SQLException {
4105:                checkExecuted();
4106:                Object value;
4107:
4108:                // sanity check.
4109:                checkIndex(columnIndex);
4110:                // make sure the cursor is on a valid row
4111:                checkCursor();
4112:
4113:                setLastValueNull(false);
4114:                value = getCurrentRow().getColumnObject(columnIndex);
4115:
4116:                // check for SQL NULL
4117:                if (value == null) {
4118:                    setLastValueNull(true);
4119:                    return null;
4120:                }
4121:
4122:                value = convertTemporal(value, rowSetMD
4123:                        .getColumnType(columnIndex), java.sql.Types.TIME);
4124:
4125:                // create a default calendar
4126:                Calendar defaultCal = Calendar.getInstance();
4127:                // set the time in the default calendar
4128:                defaultCal.setTime((java.util.Date) value);
4129:
4130:                /*
4131:                 * Now we can pull the pieces of the date out
4132:                 * of the default calendar and put them into
4133:                 * the user provided calendar
4134:                 */
4135:                cal.set(Calendar.HOUR_OF_DAY, defaultCal
4136:                        .get(Calendar.HOUR_OF_DAY));
4137:                cal.set(Calendar.MINUTE, defaultCal.get(Calendar.MINUTE));
4138:                cal.set(Calendar.SECOND, defaultCal.get(Calendar.SECOND));
4139:
4140:                return new java.sql.Time(cal.getTime().getTime());
4141:            }
4142:
4143:            public java.sql.Time getTime(String columnName, Calendar cal)
4144:                    throws SQLException {
4145:                checkExecuted();
4146:                return getTime(getColIdxByName(columnName), cal);
4147:            }
4148:
4149:            public java.sql.Timestamp getTimestamp(int columnIndex, Calendar cal)
4150:                    throws SQLException {
4151:                checkExecuted();
4152:                Object value;
4153:
4154:                // sanity check.
4155:                checkIndex(columnIndex);
4156:                // make sure the cursor is on a valid row
4157:                checkCursor();
4158:
4159:                setLastValueNull(false);
4160:                value = getCurrentRow().getColumnObject(columnIndex);
4161:
4162:                // check for SQL NULL
4163:                if (value == null) {
4164:                    setLastValueNull(true);
4165:                    return null;
4166:                }
4167:
4168:                value = convertTemporal(value, rowSetMD
4169:                        .getColumnType(columnIndex), java.sql.Types.TIMESTAMP);
4170:
4171:                // create a default calendar
4172:                Calendar defaultCal = Calendar.getInstance();
4173:                // set the time in the default calendar
4174:                defaultCal.setTime((java.util.Date) value);
4175:
4176:                /*
4177:                 * Now we can pull the pieces of the date out
4178:                 * of the default calendar and put them into
4179:                 * the user provided calendar
4180:                 */
4181:                cal.set(Calendar.YEAR, defaultCal.get(Calendar.YEAR));
4182:                cal.set(Calendar.MONTH, defaultCal.get(Calendar.MONTH));
4183:                cal.set(Calendar.DAY_OF_MONTH, defaultCal
4184:                        .get(Calendar.DAY_OF_MONTH));
4185:                cal.set(Calendar.HOUR_OF_DAY, defaultCal
4186:                        .get(Calendar.HOUR_OF_DAY));
4187:                cal.set(Calendar.MINUTE, defaultCal.get(Calendar.MINUTE));
4188:                cal.set(Calendar.SECOND, defaultCal.get(Calendar.SECOND));
4189:
4190:                return new java.sql.Timestamp(cal.getTime().getTime());
4191:            }
4192:
4193:            public java.sql.Timestamp getTimestamp(String columnName,
4194:                    Calendar cal) throws SQLException {
4195:                checkExecuted();
4196:                return getTimestamp(getColIdxByName(columnName), cal);
4197:            }
4198:
4199:            /*
4200:             * RowSetInternal Interface
4201:             */
4202:
4203:            /**
4204:             * Retrieves the <code>Connection</code> object passed to this
4205:             * <code>CachedRowSetXImpl</code> object.  This connection may be
4206:             * used to populate this rowset with data or to write data back
4207:             * to its underlying data source.
4208:             *
4209:             * @return the <code>Connection</code> object passed to this rowset;
4210:             *         may be <code>null</code> if there is no connection
4211:             * @throws SQLException if an error occurs
4212:             */
4213:            public Connection getConnection() throws SQLException {
4214:
4215:                return conn;
4216:            }
4217:
4218:            /**
4219:             * Given a dataSourceName, url, username and password, create a connection
4220:             * If dataSourceName is null, assume a Driver Manager connection
4221:             * If username is null, don't pass them to the lookup method
4222:             *
4223:             * @return the <code>Connection</code> object
4224:             *
4225:             * @throws SQLException if an error occurs
4226:             */
4227:            static private Connection getConnection(String dataSourceName,
4228:                    String url, String username, String password)
4229:                    throws SQLException {
4230:
4231:                Log.getLogger()
4232:                        .entering(
4233:                                "CachedRowSetXImpl",
4234:                                "getConnection()",
4235:                                new Object[] { dataSourceName, url, username,
4236:                                        password });
4237:
4238:                Connection conn = null;
4239:                if (dataSourceName != null) {
4240:                    // Connect using JNDI.
4241:                    try {
4242:                        Context ctx = new InitialContext();
4243:                        Log.getLogger().finest(
4244:                                "About to get DataSource, ctx: " + ctx);
4245:
4246:                        DataSource ds = (DataSource) ctx.lookup(dataSourceName);
4247:
4248:                        Log.getLogger().finest(
4249:                                "About to get connection, DataSource: " + ds);
4250:
4251:                        if (username == null || username.equals("")) { //NOI18N
4252:                            conn = ds.getConnection();
4253:                        } else {
4254:                            conn = ds.getConnection(username, password);
4255:                        }
4256:                    } catch (javax.naming.NamingException ex) {
4257:                        Log.getLogger().finest(
4258:                                "Caught exception: " + ex + " "
4259:                                        + ex.getMessage());
4260:                        throw new SQLException(rb
4261:                                .getString("UNABLE_TO_CONNECT")
4262:                                + ex.getMessage()); //NOI18N
4263:                    }
4264:                } else if (url != null) {
4265:                    // Check only for url != null because
4266:                    // user, passwd can be null
4267:                    // Connect using the driver manager.
4268:                    conn = DriverManager.getConnection(url, username, password);
4269:                } else {
4270:                    throw new SQLException(rb
4271:                            .getString("BOTH_DS_AND_URL_CANNOT_BE_NULL")); //NOI18N
4272:                }
4273:                return conn;
4274:            }
4275:
4276:            public void setMetaData(RowSetMetaData md) throws SQLException {
4277:                rowSetMD = md;
4278:            }
4279:
4280:            // Implemented in CachedRowSetXImpl
4281:            public abstract ResultSet getOriginal() throws SQLException;
4282:
4283:            // Implemented in CachedRowSetXImpl
4284:            public abstract ResultSet getOriginalRow() throws SQLException;
4285:
4286:            public void setOriginalRow() throws SQLException {
4287:                checkExecuted();
4288:                if (onInsertRow == true) {
4289:                    throw new SQLException(rb
4290:                            .getString("INVALID_INSERT_ROW_OP")); //NOI18N
4291:                }
4292:
4293:                Row row = (Row) getCurrentRow();
4294:                makeRowOriginal(row);
4295:
4296:                // this can happen if deleted rows are being shown
4297:                if (row.getDeleted() == true) {
4298:                    removeCurrentRow();
4299:                    --numRows;
4300:                }
4301:            }
4302:
4303:            private void makeRowOriginal(Row row) {
4304:                if (row.getInserted() == true) {
4305:                    row.clearInserted();
4306:                }
4307:
4308:                if (row.getUpdated() == true) {
4309:                    row.moveCurrentToOrig();
4310:                }
4311:            }
4312:
4313:            public void setOriginal() throws SQLException {
4314:                checkExecuted();
4315:                for (Iterator i = rvh.iterator(); i.hasNext();) {
4316:                    Row row = (Row) i.next();
4317:                    makeRowOriginal(row);
4318:                    // remove deleted rows from the collection.
4319:                    if (row.getDeleted() == true) {
4320:                        i.remove();
4321:                        --numRows;
4322:                    }
4323:                }
4324:                numDeleted = 0;
4325:
4326:                // notify any listeners that the rowset has changed
4327:                notifyRowSetChanged();
4328:            }
4329:
4330:            public String getTableName() throws SQLException {
4331:                return tableName;
4332:            }
4333:
4334:            public void setTableName(String tabName) throws SQLException {
4335:                if (tabName == null)
4336:                    throw new SQLException(rb
4337:                            .getString("TABLENAME_CANNOT_BE_NULL")); //NOI18N
4338:                else
4339:                    tableName = new String(tabName);
4340:            }
4341:
4342:            public int[] getKeyColumns() throws SQLException {
4343:                return keyCols;
4344:            }
4345:
4346:            public void setKeyColumns(int[] keys) throws SQLException {
4347:                int numCols = 0;
4348:                if (rowSetMD != null) {
4349:                    numCols = rowSetMD.getColumnCount();
4350:                    if (keys.length > numCols)
4351:                        throw new SQLException(rb.getString("INVALID_KEY_COLS")); //NOI18N
4352:                }
4353:                keyCols = new int[keys.length];
4354:                for (int i = 0; i < keys.length; i++) {
4355:                    if (rowSetMD != null && (keys[i] <= 0 || keys[i] > numCols)) {
4356:                        throw new SQLException(MessageFormat.format(rb
4357:                                .getString("INVALID_COLUMN_INDEX"), //NOI18N
4358:                                new Object[] { new Integer(keys[i]) }));
4359:                    }
4360:                    keyCols[i] = keys[i];
4361:                }
4362:            }
4363:
4364:            public void updateRef(int columnIndex, java.sql.Ref ref)
4365:                    throws SQLException {
4366:                checkExecuted();
4367:                // sanity check.
4368:                checkIndex(columnIndex);
4369:                // make sure the cursor is on a valid row
4370:                checkCursor();
4371:
4372:                // SerialClob will help in getting the byte array and storing it.
4373:                // We need to be checking DatabaseMetaData.locatorsUpdatorCopy()
4374:                // or through RowSetMetaData.locatorsUpdatorCopy()
4375:                getCurrentRow()
4376:                        .setColumnObject(columnIndex, new SerialRef(ref));
4377:            }
4378:
4379:            public void updateRef(String columnName, java.sql.Ref ref)
4380:                    throws SQLException {
4381:                checkExecuted();
4382:                updateRef(getColIdxByName(columnName), ref);
4383:            }
4384:
4385:            public void updateClob(int columnIndex, Clob c) throws SQLException {
4386:                checkExecuted();
4387:                // sanity check.
4388:                checkIndex(columnIndex);
4389:                // make sure the cursor is on a valid row
4390:                checkCursor();
4391:
4392:                // SerialClob will help in getting the byte array and storing it.
4393:                // We need to be checking DatabaseMetaData.locatorsUpdatorCopy()
4394:                // or through RowSetMetaData.locatorsUpdatorCopy()
4395:
4396:                if (dbmslocatorsUpdateCopy) {
4397:                    getCurrentRow().setColumnObject(columnIndex,
4398:                            new SerialClob(c));
4399:                } else {
4400:                    throw new SQLException(rb
4401:                            .getString("OP_NOT_SUPPORTED_BY_DB")); //NOI18N
4402:                }
4403:            }
4404:
4405:            public void updateClob(String columnName, Clob c)
4406:                    throws SQLException {
4407:                checkExecuted();
4408:                updateClob(getColIdxByName(columnName), c);
4409:            }
4410:
4411:            public void updateBlob(int columnIndex, Blob b) throws SQLException {
4412:                checkExecuted();
4413:                // sanity check.
4414:                checkIndex(columnIndex);
4415:                // make sure the cursor is on a valid row
4416:                checkCursor();
4417:
4418:                // SerialBlob will help in getting the byte array and storing it.
4419:                // We need to be checking DatabaseMetaData.locatorsUpdatorCopy()
4420:                // or through RowSetMetaData.locatorsUpdatorCopy()
4421:
4422:                if (dbmslocatorsUpdateCopy) {
4423:                    getCurrentRow().setColumnObject(columnIndex,
4424:                            new SerialBlob(b));
4425:                } else {
4426:                    throw new SQLException(rb
4427:                            .getString("OP_NOT_SUPPORTED_BY_DB")); //NOI18N
4428:                }
4429:            }
4430:
4431:            public void updateBlob(String columnName, Blob b)
4432:                    throws SQLException {
4433:                checkExecuted();
4434:                updateBlob(getColIdxByName(columnName), b);
4435:            }
4436:
4437:            public void updateArray(int columnIndex, Array a)
4438:                    throws SQLException {
4439:                checkExecuted();
4440:                // sanity check.
4441:                checkIndex(columnIndex);
4442:                // make sure the cursor is on a valid row
4443:                checkCursor();
4444:
4445:                // SerialArray will help in getting the byte array and storing it.
4446:                // We need to be checking DatabaseMetaData.locatorsUpdatorCopy()
4447:                // or through RowSetMetaData.locatorsUpdatorCopy()
4448:                getCurrentRow()
4449:                        .setColumnObject(columnIndex, new SerialArray(a));
4450:            }
4451:
4452:            public void updateArray(String columnName, Array a)
4453:                    throws SQLException {
4454:                checkExecuted();
4455:                updateArray(getColIdxByName(columnName), a);
4456:            }
4457:
4458:            public java.net.URL getURL(int columnIndex) throws SQLException {
4459:                checkExecuted();
4460:
4461:                java.net.URL value;
4462:
4463:                // sanity check.
4464:                checkIndex(columnIndex);
4465:                // make sure the cursor is on a valid row
4466:                checkCursor();
4467:
4468:                if (rowSetMD.getColumnType(columnIndex) != java.sql.Types.DATALINK) {
4469:                    throw new SQLException(rb.getString("DATATYPE_MISMATCH")); //NOI18N
4470:                }
4471:
4472:                setLastValueNull(false);
4473:                value = (java.net.URL) (getCurrentRow()
4474:                        .getColumnObject(columnIndex));
4475:
4476:                // check for SQL NULL
4477:                if (value == null) {
4478:                    setLastValueNull(true);
4479:                    return null;
4480:                }
4481:
4482:                return value;
4483:            }
4484:
4485:            public java.net.URL getURL(String columnName) throws SQLException {
4486:                checkExecuted();
4487:                return getURL(getColIdxByName(columnName));
4488:
4489:            }
4490:
4491:            public RowSetWarning getRowSetWarnings() {
4492:                try {
4493:                    notifyCursorMoved();
4494:                } catch (SQLException e) {
4495:                } // mask exception
4496:                return rowsetWarning;
4497:            }
4498:
4499:            public void commit() throws SQLException {
4500:                checkExecuted();
4501:                if (conn != null) {
4502:                    conn.commit();
4503:                }
4504:            }
4505:
4506:            public void rollback() throws SQLException {
4507:                checkExecuted();
4508:                if (conn != null) {
4509:                    conn.rollback();
4510:                }
4511:            }
4512:
4513:            public void rollback(Savepoint s) throws SQLException {
4514:                checkExecuted();
4515:                if (conn != null) {
4516:                    conn.rollback(s);
4517:                }
4518:            }
4519:
4520:            public void unsetMatchColumn(int[] columnIdxes) throws SQLException {
4521:
4522:                int i_val;
4523:                for (int j = 0; j < columnIdxes.length; j++) {
4524:                    i_val = (Integer.parseInt(iMatchColumns.get(j).toString()));
4525:                    if (columnIdxes[j] != i_val) {
4526:                        throw new SQLException(rb
4527:                                .getString("MATCH_COLUMNS_NOT_THE_SAME")); //NOI18N
4528:                    }
4529:                }
4530:
4531:                for (int i = 0; i < columnIdxes.length; i++) {
4532:                    iMatchColumns.set(i, new Integer(-1));
4533:                }
4534:            }
4535:
4536:            public void unsetMatchColumn(String[] columnIdxes)
4537:                    throws SQLException {
4538:
4539:                for (int j = 0; j < columnIdxes.length; j++) {
4540:                    if (!columnIdxes[j].equals(strMatchColumns.get(j))) {
4541:                        throw new SQLException(rb
4542:                                .getString("MATCH_COLUMNS_NOT_THE_SAME")); //NOI18N
4543:                    }
4544:                }
4545:
4546:                for (int i = 0; i < columnIdxes.length; i++) {
4547:                    strMatchColumns.set(i, null);
4548:                }
4549:            }
4550:
4551:            public String[] getMatchColumnNames() throws SQLException {
4552:
4553:                String[] str_temp = new String[strMatchColumns.size()];
4554:
4555:                if (strMatchColumns.get(0) == null) {
4556:                    throw new SQLException(rb
4557:                            .getString("SET_MATCH_COLUMNS_BEFORE_GETTING")); //NOI18N
4558:                }
4559:
4560:                strMatchColumns.copyInto(str_temp);
4561:                return str_temp;
4562:            }
4563:
4564:            public int[] getMatchColumnIndexes() throws SQLException {
4565:
4566:                Integer[] int_temp = new Integer[iMatchColumns.size()];
4567:                int[] i_temp = new int[iMatchColumns.size()];
4568:                int i_val;
4569:
4570:                i_val = ((Integer) iMatchColumns.get(0)).intValue();
4571:
4572:                if (i_val == -1) {
4573:                    throw new SQLException(rb
4574:                            .getString("SET_MATCH_COLUMNS_BEFORE_GETTING")); //NOI18N
4575:                }
4576:
4577:                iMatchColumns.copyInto(int_temp);
4578:
4579:                for (int i = 0; i < int_temp.length; i++) {
4580:                    i_temp[i] = (int_temp[i]).intValue();
4581:                }
4582:
4583:                return i_temp;
4584:            }
4585:
4586:            public void setMatchColumn(int[] columnIdxes) throws SQLException {
4587:
4588:                for (int j = 0; j < columnIdxes.length; j++) {
4589:                    if (columnIdxes[j] < 0) {
4590:                        throw new SQLException(rb
4591:                                .getString("MATCH_COL_MUST_BE_GT_0")); //NOI18N
4592:                    }
4593:                }
4594:                for (int i = 0; i < columnIdxes.length; i++) {
4595:                    iMatchColumns.add(i, new Integer(columnIdxes[i]));
4596:                }
4597:            }
4598:
4599:            public void setMatchColumn(String[] columnNames)
4600:                    throws SQLException {
4601:
4602:                for (int j = 0; j < columnNames.length; j++) {
4603:                    if (columnNames[j] == null || columnNames[j].equals("")) { //NOI18N
4604:                        throw new SQLException(rb
4605:                                .getString("MATCH_COL_CANNOT_BE_NULL_OR_EMPTY")); //NOI18N
4606:                    }
4607:                }
4608:                for (int i = 0; i < columnNames.length; i++) {
4609:                    strMatchColumns.add(i, columnNames[i]);
4610:                }
4611:            }
4612:
4613:            public void setMatchColumn(int columnIdx) throws SQLException {
4614:                // validate, if col is ok to be set
4615:                if (columnIdx < 0) {
4616:                    throw new SQLException(rb
4617:                            .getString("COL_ID_HAS_TO_BE_GT_0")); //NOI18N
4618:                } else {
4619:                    // set iMatchColumn
4620:                    iMatchColumns.set(0, new Integer(columnIdx));
4621:                    //strMatchColumn = null;
4622:                }
4623:            }
4624:
4625:            public void setMatchColumn(String columnName) throws SQLException {
4626:                // validate, if col is ok to be set
4627:                columnName = columnName.trim();
4628:                if (columnName == "" || columnName.equals(null)) { //NOI18N
4629:                    throw new SQLException(rb
4630:                            .getString("COL_ID_HAS_TO_BE_NON_NULL")); //NOI18N
4631:                } else {
4632:                    // set strMatchColumn
4633:                    strMatchColumns.set(0, columnName);
4634:                    //iMatchColumn = -1;
4635:                }
4636:            }
4637:
4638:            public void unsetMatchColumn(int columnIdx) throws SQLException {
4639:                // check if we are unsetting the SAME column
4640:                if (!iMatchColumns.get(0).equals(new Integer(columnIdx))) {
4641:                    throw new SQLException(rb
4642:                            .getString("COL_UNSET_NOT_SAME_AS_SET")); //NOI18N
4643:                } else if (strMatchColumns.get(0) != null) {
4644:                    throw new SQLException(rb
4645:                            .getString("USE_COL_NAME_AS_ARG_TO_UNSETMATCHCOL")); //NOI18N
4646:                } else {
4647:                    // that is, we are unsetting it.
4648:                    iMatchColumns.set(0, new Integer(-1));
4649:                }
4650:            }
4651:
4652:            public void unsetMatchColumn(String columnName) throws SQLException {
4653:                // check if we are unsetting the same column
4654:                columnName = columnName.trim();
4655:
4656:                if (!((strMatchColumns.get(0)).equals(columnName))) {
4657:                    throw new SQLException(rb
4658:                            .getString("COL_UNSET_NOT_SAME_AS_SET")); //NOI18N
4659:                } else if (((Integer) (iMatchColumns.get(0))).intValue() > 0) {
4660:                    throw new SQLException(rb
4661:                            .getString("USE_COL_ID_AS_ARG_TO_UNSETMATCHCOL")); //NOI18N
4662:                } else {
4663:                    strMatchColumns.set(0, null); // that is, we are unsetting it.
4664:                }
4665:            }
4666:
4667:            public void rowSetPopulated(RowSetEvent event, int numRows)
4668:                    throws SQLException {
4669:
4670:                if (numRows < 0 || numRows < getFetchSize()) {
4671:                    throw new SQLException(
4672:                            rb
4673:                                    .getString("NUM_ROWS_CANNOT_BE_LT_0_OR_LT_FETCHSIZE")); // NOI18N
4674:                }
4675:
4676:                if (size() % numRows == 0) {
4677:                    RowSetEvent event_temp = new RowSetEvent(this );
4678:                    event = event_temp;
4679:                    notifyRowSetChanged();
4680:                }
4681:            }
4682:
4683:            public void populate(ResultSet data, int start) throws SQLException {
4684:
4685:                int rowsFetched;
4686:                Row currentRow;
4687:                int numCols;
4688:                int i;
4689:                Map map = getTypeMap();
4690:                Object obj;
4691:                int mRows;
4692:
4693:                cursorPos = 0;
4694:                if (populatecallcount == 0) {
4695:                    if (start < 0) {
4696:                        throw new SQLException(rb
4697:                                .getString("START_POS_CANNOT_BE_NEGATIVE")); //NOI18N
4698:                    }
4699:                    if (getMaxRows() == 0) {
4700:                        data.absolute(start);
4701:                        while (data.next()) {
4702:                            totalRows++;
4703:                        }
4704:                        totalRows++;
4705:                    }
4706:                    startPos = start;
4707:                }
4708:                populatecallcount = populatecallcount + 1;
4709:                resultSet = data;
4710:                if ((endPos - startPos) >= getMaxRows() && (getMaxRows() > 0)) {
4711:                    endPos = prevEndPos;
4712:                    pagenotend = false;
4713:                    return;
4714:                }
4715:
4716:                if ((maxRowsreached != getMaxRows() || maxRowsreached != totalRows)
4717:                        && pagenotend) {
4718:                    startPrev = start - getPageSize();
4719:                }
4720:
4721:                if (pageSize == 0) {
4722:                    prevEndPos = endPos;
4723:                    endPos = start + getMaxRows();
4724:                } else {
4725:                    prevEndPos = endPos;
4726:                    endPos = start + getPageSize();
4727:                }
4728:
4729:                if (start == 1) {
4730:                    resultSet.beforeFirst();
4731:                } else {
4732:                    resultSet.absolute(start - 1);
4733:                }
4734:                if (pageSize == 0) {
4735:                    rvh = new Vector(getMaxRows());
4736:
4737:                } else {
4738:                    rvh = new Vector(getPageSize());
4739:                }
4740:
4741:                if (data == null) {
4742:                    throw new SQLException(rb
4743:                            .getString("INVALID_RESULTSET_SUPPLIED")); //NOI18N
4744:                }
4745:
4746:                // get the meta data for this ResultSet
4747:                rsmd = data.getMetaData();
4748:
4749:                // set up the metadata
4750:                rowSetMD = new RowSetMetaDataXImpl();
4751:                initMetaData(rowSetMD, rsmd);
4752:
4753:                // release the meta-data so that aren't tempted to use it.
4754:                rsmd = null;
4755:                numCols = rowSetMD.getColumnCount();
4756:                mRows = this .getMaxRows();
4757:                rowsFetched = 0;
4758:                currentRow = null;
4759:
4760:                if (!data.next() && mRows == 0) {
4761:                    endPos = prevEndPos;
4762:                    pagenotend = false;
4763:                    return;
4764:                }
4765:
4766:                data.previous();
4767:
4768:                while (data.next()) {
4769:
4770:                    currentRow = new Row(numCols);
4771:                    if (pageSize == 0) {
4772:                        if (rowsFetched >= mRows && mRows > 0) {
4773:                            rowsetWarning.setNextException(new SQLException(rb
4774:                                    .getString("MAX_ROWS_EXCEEDED"))); //NOI18N
4775:                            break;
4776:                        }
4777:                    } else {
4778:                        if ((rowsFetched >= pageSize)
4779:                                || (maxRowsreached >= mRows && mRows > 0)) {
4780:                            rowsetWarning.setNextException(new SQLException(rb
4781:                                    .getString("MAX_ROWS_EXCEEDED"))); //NOI18N
4782:                            break;
4783:                        }
4784:                    }
4785:
4786:                    for (i = 1; i <= numCols; i++) {
4787:                        /*
4788:                         * check if the user has set a map. If no map
4789:                         * is set then use plain getObject. This lets
4790:                         * us work with drivers that do not support
4791:                         * getObject with a map in fairly sensible way
4792:                         */
4793:                        if (map == null) {
4794:                            obj = data.getObject(i);
4795:                        } else {
4796:                            obj = data.getObject(i, map);
4797:                        }
4798:                        /*
4799:                         * the following block checks for the various
4800:                         * types that we have to serialize in order to
4801:                         * store - right now only structs have been tested
4802:                         */
4803:                        if (obj instanceof  Struct) {
4804:                            obj = new SerialStruct((Struct) obj, map);
4805:                        } else if (obj instanceof  SQLData) {
4806:                            obj = new SerialStruct((SQLData) obj, map);
4807:                        } else if (obj instanceof  Blob) {
4808:                            obj = new SerialBlob((Blob) obj);
4809:                        } else if (obj instanceof  Clob) {
4810:                            obj = new SerialClob((Clob) obj);
4811:                        } else if (obj instanceof  java.sql.Array) {
4812:                            obj = new SerialArray((java.sql.Array) obj, map);
4813:                        }
4814:
4815:                        ((Row) currentRow).initColumnObject(i, obj);
4816:                    }
4817:                    rowsFetched++;
4818:                    maxRowsreached++;
4819:                    rvh.add(currentRow);
4820:                }
4821:                numRows = rowsFetched;
4822:                executed = true;
4823:                // Also rowsFetched should be equal to rvh.size()
4824:                // notify any listeners that the rowset has changed
4825:                notifyRowSetChanged();
4826:
4827:            }
4828:
4829:            public boolean nextPage() throws SQLException {
4830:                // checkExecuted(); //!JK: ??
4831:
4832:                if (populatecallcount == 0) {
4833:                    throw new SQLException(rb
4834:                            .getString("INVALID_OP_ROWSET_NOT_POPULATED")); //NOI18N
4835:                }
4836:                if (populatecallcount == 1) {
4837:                    populatecallcount++;
4838:                    return pagenotend;
4839:                } else {
4840:                    onFirstPage = false;
4841:                    if (callWithCon) {
4842:                        crsReader.setStartPosition(endPos);
4843:                        crsReader.readData((RowSetInternal) this );
4844:                        resultSet = null;
4845:                    } else {
4846:                        populate(resultSet, endPos);
4847:                    }
4848:                    return pagenotend;
4849:                }
4850:            }
4851:
4852:            public void setPageSize(int size) throws SQLException {
4853:                if (size < 0) {
4854:                    throw new SQLException(rb
4855:                            .getString("PAGESIZE_MUST_BE_GE_0")); //NOI18N
4856:                }
4857:                if (size > getMaxRows() && getMaxRows() != 0) {
4858:                    throw new SQLException(rb
4859:                            .getString("PAGESIZE_MUST_BE_LE_MAXROWS")); //NOI18N
4860:                }
4861:                pageSize = size;
4862:            }
4863:
4864:            public int getPageSize() {
4865:                return pageSize;
4866:            }
4867:
4868:            public boolean previousPage() throws SQLException {
4869:                // checkExecuted(); //!JK: ??
4870:                int pS;
4871:                int mR;
4872:                int rem;
4873:
4874:                pS = getPageSize();
4875:                mR = maxRowsreached;
4876:
4877:                if (populatecallcount == 0) {
4878:                    throw new SQLException(rb
4879:                            .getString("INVALID_OP_ROWSET_NOT_POPULATED")); //NOI18N
4880:                }
4881:
4882:                if (!callWithCon) {
4883:                    if (resultSet.getType() == ResultSet.TYPE_FORWARD_ONLY) {
4884:                        throw new SQLException(rb
4885:                                .getString("RESULTSET_TYPE_FORWARD_ONLY")); //NOI18N
4886:                    }
4887:                }
4888:
4889:                pagenotend = true;
4890:
4891:                if (startPrev < startPos) {
4892:                    onFirstPage = true;
4893:                    return false;
4894:                }
4895:
4896:                if (onFirstPage) {
4897:                    return false;
4898:                }
4899:
4900:                rem = mR % pS;
4901:
4902:                if (rem == 0) {
4903:                    maxRowsreached -= (2 * pS);
4904:                    if (callWithCon) {
4905:                        crsReader.setStartPosition(startPrev);
4906:                        crsReader.readData((RowSetInternal) this );
4907:                        resultSet = null;
4908:                    } else {
4909:                        populate(resultSet, startPrev);
4910:                    }
4911:                    return true;
4912:                } else {
4913:                    maxRowsreached -= (pS + rem);
4914:                    if (callWithCon) {
4915:                        crsReader.setStartPosition(startPrev);
4916:                        crsReader.readData((RowSetInternal) this );
4917:                        resultSet = null;
4918:                    } else {
4919:                        populate(resultSet, startPrev);
4920:                    }
4921:                    return true;
4922:                }
4923:            }
4924:
4925:            private String catalogName = null;
4926:
4927:            /**
4928:             * {@inheritDoc}
4929:             */
4930:            public String getCatalogName() {
4931:                return catalogName;
4932:            }
4933:
4934:            /**
4935:             * {@inheritDoc}
4936:             */
4937:            public void setCatalogName(String catalogName) {
4938:                this .catalogName = catalogName;
4939:            }
4940:
4941:            private String schemaName = null;
4942:
4943:            /**
4944:             * {@inheritDoc}
4945:             */
4946:            public String getSchemaName() {
4947:                return schemaName;
4948:            }
4949:
4950:            /**
4951:             * {@inheritDoc}
4952:             */
4953:            public void setSchemaName(String schemaName) {
4954:                this .schemaName = schemaName;
4955:            }
4956:
4957:            private String[] columnCatalogNames = null;
4958:
4959:            /**
4960:             * {@inheritDoc}
4961:             */
4962:            public String[] getColumnCatalogNames() {
4963:                return columnCatalogNames;
4964:            }
4965:
4966:            /**
4967:             * {@inheritDoc}
4968:             */
4969:            public String getColumnCatalogNames(int index) {
4970:                return columnCatalogNames[index];
4971:            }
4972:
4973:            /**
4974:             * {@inheritDoc}
4975:             */
4976:            public void setColumnCatalogNames(String[] columnCatalogNames) {
4977:                this .columnCatalogNames = columnCatalogNames;
4978:            }
4979:
4980:            /**
4981:             * {@inheritDoc}
4982:             */
4983:            public void setColumnCatalogNames(int index,
4984:                    String columnCatalogName) {
4985:                this .columnCatalogNames[index] = columnCatalogName;
4986:            }
4987:
4988:            private String[] columnSchemaNames = null;
4989:
4990:            /**
4991:             * {@inheritDoc}
4992:             */
4993:            public String[] getColumnSchemaNames() {
4994:                return columnSchemaNames;
4995:            }
4996:
4997:            /**
4998:             * {@inheritDoc}
4999:             */
5000:            public String getColumnSchemaNames(int index) {
5001:                return columnSchemaNames[index];
5002:            }
5003:
5004:            /**
5005:             * {@inheritDoc}
5006:             */
5007:            public void setColumnSchemaNames(String[] columnSchemaNames) {
5008:                this .columnSchemaNames = columnSchemaNames;
5009:            }
5010:
5011:            /**
5012:             * {@inheritDoc}
5013:             */
5014:            public void setColumnSchemaNames(int index, String columnSchemaName) {
5015:                this .columnSchemaNames[index] = columnSchemaName;
5016:            }
5017:
5018:            private String[] columnTableNames = null;
5019:
5020:            /**
5021:             * {@inheritDoc}
5022:             */
5023:            public String[] getColumnTableNames() {
5024:                return columnTableNames;
5025:            }
5026:
5027:            /**
5028:             * {@inheritDoc}
5029:             */
5030:            public String getColumnTableNames(int index) {
5031:                return columnTableNames[index];
5032:            }
5033:
5034:            /**
5035:             * {@inheritDoc}
5036:             */
5037:            public void setColumnTableNames(String[] columnTableNames) {
5038:                this .columnTableNames = columnTableNames;
5039:            }
5040:
5041:            /**
5042:             * {@inheritDoc}
5043:             */
5044:            public void setColumnTableNames(int index, String columnTableName) {
5045:                this .columnTableNames[index] = columnTableName;
5046:            }
5047:
5048:            private String[] columnNames = null;
5049:
5050:            /**
5051:             * {@inheritDoc}
5052:             */
5053:            public String[] getColumnNames() {
5054:                return columnNames;
5055:            }
5056:
5057:            /**
5058:             * {@inheritDoc}
5059:             */
5060:            public String getColumnNames(int index) {
5061:                return columnNames[index];
5062:            }
5063:
5064:            /**
5065:             * {@inheritDoc}
5066:             */
5067:            public void setColumnNames(String[] columnNames) {
5068:                this .columnNames = columnNames;
5069:            }
5070:
5071:            /**
5072:             * {@inheritDoc}
5073:             */
5074:            public void setColumnNames(int index, String columnName) {
5075:                this .columnNames[index] = columnName;
5076:            }
5077:
5078:            private boolean[] insertableColumns = null;
5079:
5080:            /**
5081:             * {@inheritDoc}
5082:             */
5083:            public boolean[] getInsertableColumns() {
5084:                return insertableColumns;
5085:            }
5086:
5087:            /**
5088:             * {@inheritDoc}
5089:             */
5090:            public boolean getInsertableColumns(int index) {
5091:                return insertableColumns[index];
5092:            }
5093:
5094:            /**
5095:             * {@inheritDoc}
5096:             */
5097:            public void setInsertableColumns(boolean[] insertableColumns) {
5098:                this .insertableColumns = insertableColumns;
5099:            }
5100:
5101:            /**
5102:             * {@inheritDoc}
5103:             */
5104:            public void setInsertableColumns(int index, boolean insertableColumn) {
5105:                this .insertableColumns[index] = insertableColumn;
5106:            }
5107:
5108:            private boolean[] updatableColumns = null;
5109:
5110:            /**
5111:             * {@inheritDoc}
5112:             */
5113:            public boolean[] getUpdatableColumns() {
5114:                return updatableColumns;
5115:            }
5116:
5117:            /**
5118:             * {@inheritDoc}
5119:             */
5120:            public boolean getUpdatableColumns(int index) {
5121:                return updatableColumns[index];
5122:            }
5123:
5124:            /**
5125:             * {@inheritDoc}
5126:             */
5127:            public void setUpdatableColumns(boolean[] updatableColumns) {
5128:                this .updatableColumns = updatableColumns;
5129:            }
5130:
5131:            /**
5132:             * {@inheritDoc}
5133:             */
5134:            public void setUpdatableColumns(int index, boolean updatableColumn) {
5135:                this .updatableColumns[index] = updatableColumn;
5136:            }
5137:
5138:            private boolean printStatements;
5139:
5140:            /**
5141:             * {@inheritDoc}
5142:             */
5143:            public boolean getPrintStatements() {
5144:                return printStatements;
5145:            }
5146:
5147:            /**
5148:             * {@inheritDoc}
5149:             */
5150:            public void setPrintStatements(boolean printStatements) {
5151:                this .printStatements = printStatements;
5152:            }
5153:
5154:        } //end class
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.