Source Code Cross Referenced for CachedRowSetReader.java in  » 6.0-JDK-Modules-com.sun » rowset » com » sun » rowset » internal » 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 » 6.0 JDK Modules com.sun » rowset » com.sun.rowset.internal 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        /*
002:         * Copyright 2003-2006 Sun Microsystems, Inc.  All Rights Reserved.
003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004:         *
005:         * This code is free software; you can redistribute it and/or modify it
006:         * under the terms of the GNU General Public License version 2 only, as
007:         * published by the Free Software Foundation.  Sun designates this
008:         * particular file as subject to the "Classpath" exception as provided
009:         * by Sun in the LICENSE file that accompanied this code.
010:         *
011:         * This code is distributed in the hope that it will be useful, but WITHOUT
012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
014:         * version 2 for more details (a copy is included in the LICENSE file that
015:         * accompanied this code).
016:         *
017:         * You should have received a copy of the GNU General Public License version
018:         * 2 along with this work; if not, write to the Free Software Foundation,
019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020:         *
021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022:         * CA 95054 USA or visit www.sun.com if you need additional information or
023:         * have any questions.
024:         */
025:
026:        package com.sun.rowset.internal;
027:
028:        import java.sql.*;
029:        import javax.sql.*;
030:        import javax.naming.*;
031:        import java.io.*;
032:        import java.lang.reflect.*;
033:
034:        import com.sun.rowset.*;
035:        import javax.sql.rowset.*;
036:        import javax.sql.rowset.spi.*;
037:
038:        /**
039:         * The facility called by the <code>RIOptimisticProvider</code> object 
040:         * internally to read data into it.  The calling <code>RowSet</code> object
041:         * must have implemented the <code>RowSetInternal</code> interface
042:         * and have the standard <code>CachedRowSetReader</code> object set as its
043:         * reader.
044:         * <P>
045:         * This implementation always reads all rows of the data source,
046:         * and it assumes that the <code>command</code> property for the caller
047:         * is set with a query that is appropriate for execution by a 
048:         * <code>PreparedStatement</code> object.
049:         * <P>
050:         * Typically the <code>SyncFactory</code> manages the <code>RowSetReader</code> and
051:         * the <code>RowSetWriter</code> implementations using <code>SyncProvider</code> objects.
052:         * Standard JDBC RowSet implementations provide an object instance of this
053:         * reader by invoking the <code>SyncProvider.getRowSetReader()</code> method.
054:         *
055:         * @version 0.2
056:         * @author Jonathan Bruce
057:         * @see javax.sql.rowset.spi.SyncProvider
058:         * @see javax.sql.rowset.spi.SyncFactory
059:         * @see javax.sql.rowset.spi.SyncFactoryException
060:         */
061:        public class CachedRowSetReader implements  RowSetReader, Serializable {
062:
063:            /**
064:             * The field that keeps track of whether the writer associated with 
065:             * this <code>CachedRowSetReader</code> object's rowset has been called since 
066:             * the rowset was populated.
067:             * <P>
068:             * When this <code>CachedRowSetReader</code> object reads data into
069:             * its rowset, it sets the field <code>writerCalls</code> to 0.
070:             * When the writer associated with the rowset is called to write
071:             * data back to the underlying data source, its <code>writeData</code>
072:             * method calls the method <code>CachedRowSetReader.reset</code>,
073:             * which increments <code>writerCalls</code> and returns <code>true</code>
074:             * if <code>writerCalls</code> is 1. Thus, <code>writerCalls</code> equals
075:             * 1 after the first call to <code>writeData</code> that occurs 
076:             * after the rowset has had data read into it.
077:             *
078:             * @serial
079:             */
080:            private int writerCalls = 0;
081:
082:            private boolean userCon = false;
083:
084:            private int startPosition;
085:
086:            private JdbcRowSetResourceBundle resBundle;
087:
088:            public CachedRowSetReader() {
089:                try {
090:                    resBundle = JdbcRowSetResourceBundle
091:                            .getJdbcRowSetResourceBundle();
092:                } catch (IOException ioe) {
093:                    throw new RuntimeException(ioe);
094:                }
095:            }
096:
097:            /**
098:             * Reads data from a data source and populates the given
099:             * <code>RowSet</code> object with that data.
100:             * This method is called by the rowset internally when
101:             * the application invokes the method <code>execute</code>
102:             * to read a new set of rows.
103:             * <P>
104:             * After clearing the rowset of its contents, if any, and setting
105:             * the number of writer calls to <code>0</code>, this reader calls
106:             * its <code>connect</code> method to make
107:             * a connection to the rowset's data source. Depending on which
108:             * of the rowset's properties have been set, the <code>connect</code>
109:             * method will use a <code>DataSource</code> object or the
110:             * <code>DriverManager</code> facility to make a connection to the
111:             * data source. 
112:             * <P>
113:             * Once the connection to the data source is made, this reader
114:             * executes the query in the calling <code>CachedRowSet</code> object's 
115:             * <code>command</code> property. Then it calls the rowset's 
116:             * <code>populate</code> method, which reads data from the 
117:             * <code>ResultSet</code> object produced by executing the rowset's
118:             * command. The rowset is then populated with this data.
119:             * <P>
120:             * This method's final act is to close the connection it made, thus
121:             * leaving the rowset disconnected from its data source.
122:             *
123:             * @param caller a <code>RowSet</code> object that has implemented
124:             *               the <code>RowSetInternal</code> interface and had
125:             *               this <code>CachedRowSetReader</code> object set as
126:             *               its reader
127:             * @throws SQLException if there is a database access error, there is a
128:             *         problem making the connection, or the command property has not 
129:             *         been set 
130:             */
131:            public void readData(RowSetInternal caller) throws SQLException {
132:                Connection con = null;
133:                try {
134:                    CachedRowSet crs = (CachedRowSet) caller;
135:
136:                    // Get rid of the current contents of the rowset.
137:
138:                    /**
139:                     * Checking added to verify whether page size has been set or not.
140:                     * If set then do not close the object as certain parameters need
141:                     * to be maintained.
142:                     */
143:
144:                    if (crs.getPageSize() == 0 && crs.size() > 0) {
145:                        // When page size is not set,
146:                        // crs.size() will show the total no of rows.
147:                        crs.close();
148:                    }
149:
150:                    writerCalls = 0;
151:
152:                    // Get a connection.  This reader assumes that the necessary 
153:                    // properties have been set on the caller to let it supply a 
154:                    // connection.
155:                    userCon = false;
156:
157:                    con = this .connect(caller);
158:
159:                    // Check our assumptions.
160:                    if (con == null || crs.getCommand() == null)
161:                        throw new SQLException(resBundle.handleGetObject(
162:                                "crsreader.connecterr").toString());
163:
164:                    try {
165:                        con.setTransactionIsolation(crs
166:                                .getTransactionIsolation());
167:                    } catch (Exception ex) {
168:                        ;
169:                    }
170:                    // Use JDBC to read the data.
171:                    PreparedStatement pstmt = con.prepareStatement(crs
172:                            .getCommand());
173:                    // Pass any input parameters to JDBC.
174:
175:                    decodeParams(caller.getParams(), pstmt);
176:                    try {
177:                        pstmt.setMaxRows(crs.getMaxRows());
178:                        pstmt.setMaxFieldSize(crs.getMaxFieldSize());
179:                        pstmt.setEscapeProcessing(crs.getEscapeProcessing());
180:                        pstmt.setQueryTimeout(crs.getQueryTimeout());
181:                    } catch (Exception ex) {
182:                        /*
183:                         * drivers may not support the above - esp. older
184:                         * drivers being used by the bridge..
185:                         */
186:                        throw new SQLException(ex.getMessage());
187:                    }
188:
189:                    if (crs.getCommand().toLowerCase().indexOf("select") != -1) {
190:                        // can be (crs.getCommand()).indexOf("select")) == 0
191:                        // because we will be getting resultset when 
192:                        // it may be the case that some false select query with
193:                        // select coming in between instead of first.
194:
195:                        // if ((crs.getCommand()).indexOf("?")) does not return -1
196:                        // implies a Prepared Statement like query exists.
197:
198:                        ResultSet rs = pstmt.executeQuery();
199:                        if (crs.getPageSize() == 0) {
200:                            crs.populate(rs);
201:                        } else {
202:                            /**
203:                             * If page size has been set then create a ResultSet object that is scrollable using a
204:                             * PreparedStatement handle.Also call the populate(ResultSet,int) function to populate
205:                             * a page of data as specified by the page size.
206:                             */
207:                            pstmt = con.prepareStatement(crs.getCommand(),
208:                                    ResultSet.TYPE_SCROLL_INSENSITIVE,
209:                                    ResultSet.CONCUR_UPDATABLE);
210:                            decodeParams(caller.getParams(), pstmt);
211:                            try {
212:                                pstmt.setMaxRows(crs.getMaxRows());
213:                                pstmt.setMaxFieldSize(crs.getMaxFieldSize());
214:                                pstmt.setEscapeProcessing(crs
215:                                        .getEscapeProcessing());
216:                                pstmt.setQueryTimeout(crs.getQueryTimeout());
217:                            } catch (Exception ex) {
218:                                /*
219:                                 * drivers may not support the above - esp. older
220:                                 * drivers being used by the bridge..
221:                                 */
222:                                throw new SQLException(ex.getMessage());
223:                            }
224:                            rs = pstmt.executeQuery();
225:                            crs.populate(rs, startPosition);
226:                        }
227:                        rs.close();
228:                    } else {
229:                        pstmt.executeUpdate();
230:                    }
231:
232:                    // Get the data.
233:                    pstmt.close();
234:                    try {
235:                        con.commit();
236:                    } catch (SQLException ex) {
237:                        ;
238:                    }
239:                    // only close connections we created...
240:                    if (getCloseConnection() == true)
241:                        con.close();
242:                } catch (SQLException ex) {
243:                    // Throw an exception if reading fails for any reason.
244:                    throw ex;
245:                } finally {
246:                    try {
247:                        // only close connections we created...
248:                        if (con != null && getCloseConnection() == true) {
249:                            try {
250:                                if (!con.getAutoCommit()) {
251:                                    con.rollback();
252:                                }
253:                            } catch (Exception dummy) {
254:                                /*
255:                                 * not an error condition, we're closing anyway, but
256:                                 * we'd like to clean up any locks if we can since
257:                                 * it is not clear the connection pool will clean
258:                                 * these connections in a timely manner
259:                                 */
260:                            }
261:                            con.close();
262:                            con = null;
263:                        }
264:                    } catch (SQLException e) {
265:                        // will get exception if something already went wrong, but don't
266:                        // override that exception with this one
267:                    }
268:                }
269:            }
270:
271:            /**
272:             * Checks to see if the writer associated with this reader needs
273:             * to reset its state.  The writer will need to initialize its state
274:             * if new contents have been read since the writer was last called.
275:             * This method is called by the writer that was registered with 
276:             * this reader when components were being wired together.
277:             *
278:             * @return <code>true</code> if writer associated with this reader needs
279:             *         to reset the values of its fields; <code>false</code> otherwise
280:             * @throws SQLException if an access error occurs
281:             */
282:            public boolean reset() throws SQLException {
283:                writerCalls++;
284:                return writerCalls == 1;
285:            }
286:
287:            /**
288:             * Establishes a connection with the data source for the given
289:             * <code>RowSet</code> object.  If the rowset's <code>dataSourceName</code>
290:             * property has been set, this method uses the JNDI API to retrieve the
291:             * <code>DataSource</code> object that it can use to make the connection.
292:             * If the url, username, and password properties have been set, this
293:             * method uses the <code>DriverManager.getConnection</code> method to
294:             * make the connection.
295:             * <P>
296:             * This method is used internally by the reader and writer associated with
297:             * the calling <code>RowSet</code> object; an application never calls it
298:             * directly.
299:             *
300:             * @param caller a <code>RowSet</code> object that has implemented
301:             *               the <code>RowSetInternal</code> interface and had
302:             *               this <code>CachedRowSetReader</code> object set as
303:             *               its reader
304:             * @return a <code>Connection</code> object that represents a connection
305:             *         to the caller's data source 
306:             * @throws SQLException if an access error occurs
307:             */
308:            public Connection connect(RowSetInternal caller)
309:                    throws SQLException {
310:
311:                // Get a JDBC connection.
312:                if (caller.getConnection() != null) {
313:                    // A connection was passed to execute(), so use it.
314:                    // As we are using a connection the user gave us we
315:                    // won't close it.
316:                    userCon = true;
317:                    return caller.getConnection();
318:                } else if (((RowSet) caller).getDataSourceName() != null) {
319:                    // Connect using JNDI.
320:                    try {
321:                        Context ctx = new InitialContext();
322:                        DataSource ds = (DataSource) ctx
323:                                .lookup(((RowSet) caller).getDataSourceName());
324:
325:                        // Check for username, password,
326:                        // if it exists try getting a Connection handle through them
327:                        // else try without these
328:                        // else throw SQLException
329:
330:                        if (((RowSet) caller).getUsername() != null) {
331:                            return ds.getConnection(((RowSet) caller)
332:                                    .getUsername(), ((RowSet) caller)
333:                                    .getPassword());
334:                        } else {
335:                            return ds.getConnection();
336:                        }
337:                    } catch (javax.naming.NamingException ex) {
338:                        SQLException sqlEx = new SQLException(resBundle
339:                                .handleGetObject("crsreader.connect")
340:                                .toString());
341:                        sqlEx.initCause(ex);
342:                        throw sqlEx;
343:                    }
344:                } else if (((RowSet) caller).getUrl() != null) {
345:                    // Connect using the driver manager.
346:                    return DriverManager.getConnection(((RowSet) caller)
347:                            .getUrl(), ((RowSet) caller).getUsername(),
348:                            ((RowSet) caller).getPassword());
349:                } else {
350:                    return null;
351:                }
352:            }
353:
354:            /**
355:             * Sets the parameter placeholders
356:             * in the rowset's command (the given <code>PreparedStatement</code>
357:             * object) with the parameters in the given array.
358:             * This method, called internally by the method
359:             * <code>CachedRowSetReader.readData</code>, reads each parameter, and
360:             * based on its type, determines the correct
361:             * <code>PreparedStatement.setXXX</code> method to use for setting 
362:             * that parameter.
363:             *
364:             * @param params an array of parameters to be used with the given
365:             *               <code>PreparedStatement</code> object
366:             * @param pstmt  the <code>PreparedStatement</code> object that is the
367:             *               command for the calling rowset and into which
368:             *               the given parameters are to be set
369:             * @throws SQLException if an access error occurs
370:             */
371:            private void decodeParams(Object[] params, PreparedStatement pstmt)
372:                    throws SQLException {
373:                // There is a corresponding decodeParams in JdbcRowSetImpl
374:                // which does the same as this method. This is a design flaw.
375:                // Update the JdbcRowSetImpl.decodeParams when you update 
376:                // this method.
377:
378:                // Adding the same comments to JdbcRowSetImpl.decodeParams.
379:
380:                int arraySize;
381:                Object[] param = null;
382:
383:                for (int i = 0; i < params.length; i++) {
384:                    if (params[i] instanceof  Object[]) {
385:                        param = (Object[]) params[i];
386:
387:                        if (param.length == 2) {
388:                            if (param[0] == null) {
389:                                pstmt.setNull(i + 1, ((Integer) param[1])
390:                                        .intValue());
391:                                continue;
392:                            }
393:
394:                            if (param[0] instanceof  java.sql.Date
395:                                    || param[0] instanceof  java.sql.Time
396:                                    || param[0] instanceof  java.sql.Timestamp) {
397:                                System.err.println(resBundle.handleGetObject(
398:                                        "crsreader.datedetected").toString());
399:                                if (param[1] instanceof  java.util.Calendar) {
400:                                    System.err.println(resBundle
401:                                            .handleGetObject(
402:                                                    "crsreader.caldetected")
403:                                            .toString());
404:                                    pstmt.setDate(i + 1,
405:                                            (java.sql.Date) param[0],
406:                                            (java.util.Calendar) param[1]);
407:                                    continue;
408:                                } else {
409:                                    throw new SQLException(resBundle
410:                                            .handleGetObject(
411:                                                    "crsreader.paramtype")
412:                                            .toString());
413:                                }
414:                            }
415:
416:                            if (param[0] instanceof  Reader) {
417:                                pstmt.setCharacterStream(i + 1,
418:                                        (Reader) param[0], ((Integer) param[1])
419:                                                .intValue());
420:                                continue;
421:                            }
422:
423:                            /*
424:                             * What's left should be setObject(int, Object, scale)
425:                             */
426:                            if (param[1] instanceof  Integer) {
427:                                pstmt.setObject(i + 1, param[0],
428:                                        ((Integer) param[1]).intValue());
429:                                continue;
430:                            }
431:
432:                        } else if (param.length == 3) {
433:
434:                            if (param[0] == null) {
435:                                pstmt.setNull(i + 1, ((Integer) param[1])
436:                                        .intValue(), (String) param[2]);
437:                                continue;
438:                            }
439:
440:                            if (param[0] instanceof  java.io.InputStream) {
441:                                switch (((Integer) param[2]).intValue()) {
442:                                case CachedRowSetImpl.UNICODE_STREAM_PARAM:
443:                                    pstmt.setUnicodeStream(i + 1,
444:                                            (java.io.InputStream) param[0],
445:                                            ((Integer) param[1]).intValue());
446:                                case CachedRowSetImpl.BINARY_STREAM_PARAM:
447:                                    pstmt.setBinaryStream(i + 1,
448:                                            (java.io.InputStream) param[0],
449:                                            ((Integer) param[1]).intValue());
450:                                case CachedRowSetImpl.ASCII_STREAM_PARAM:
451:                                    pstmt.setAsciiStream(i + 1,
452:                                            (java.io.InputStream) param[0],
453:                                            ((Integer) param[1]).intValue());
454:                                default:
455:                                    throw new SQLException(resBundle
456:                                            .handleGetObject(
457:                                                    "crsreader.paramtype")
458:                                            .toString());
459:                                }
460:                            }
461:
462:                            /*
463:                             * no point at looking at the first element now;
464:                             * what's left must be the setObject() cases.
465:                             */
466:                            if (param[1] instanceof  Integer
467:                                    && param[2] instanceof  Integer) {
468:                                pstmt.setObject(i + 1, param[0],
469:                                        ((Integer) param[1]).intValue(),
470:                                        ((Integer) param[2]).intValue());
471:                                continue;
472:                            }
473:
474:                            throw new SQLException(resBundle.handleGetObject(
475:                                    "crsreader.paramtype").toString());
476:
477:                        } else {
478:                            // common case - this catches all SQL92 types
479:                            pstmt.setObject(i + 1, params[i]);
480:                            continue;
481:                        }
482:                    } else {
483:                        // Try to get all the params to be set here
484:                        pstmt.setObject(i + 1, params[i]);
485:
486:                    }
487:                }
488:            }
489:
490:            /**
491:             * Assists in determining whether the current connection was created by this 
492:             * CachedRowSet to ensure incorrect connections are not prematurely terminated.
493:             *
494:             * @return a boolean giving the status of whether the connection has been closed.
495:             */
496:            protected boolean getCloseConnection() {
497:                if (userCon == true)
498:                    return false;
499:
500:                return true;
501:            }
502:
503:            /**
504:             *  This sets the start position in the ResultSet from where to begin. This is
505:             * called by the Reader in the CachedRowSetImpl to set the position on the page
506:             * to begin populating from.
507:             * @param pos integer indicating the position in the <code>ResultSet</code> to begin
508:             *        populating from.
509:             */
510:            public void setStartPosition(int pos) {
511:                startPosition = pos;
512:            }
513:
514:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.