KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > derby > impl > tools > ij > utilMain


1 /*
2
3    Derby - Class org.apache.derby.impl.tools.ij.utilMain
4
5    Licensed to the Apache Software Foundation (ASF) under one or more
6    contributor license agreements. See the NOTICE file distributed with
7    this work for additional information regarding copyright ownership.
8    The ASF licenses this file to You under the Apache License, Version 2.0
9    (the "License"); you may not use this file except in compliance with
10    the License. You may obtain a copy of the License at
11
12       http://www.apache.org/licenses/LICENSE-2.0
13
14    Unless required by applicable law or agreed to in writing, software
15    distributed under the License is distributed on an "AS IS" BASIS,
16    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17    See the License for the specific language governing permissions and
18    limitations under the License.
19
20  */

21
22 package org.apache.derby.impl.tools.ij;
23                 
24 import org.apache.derby.iapi.reference.JDBC20Translation;
25 import org.apache.derby.iapi.reference.JDBC30Translation;
26
27 import org.apache.derby.tools.JDBCDisplayUtil;
28 import org.apache.derby.iapi.tools.i18n.*;
29
30 import org.apache.derby.iapi.services.info.ProductVersionHolder;
31 import org.apache.derby.iapi.services.info.ProductGenusNames;
32
33 import org.apache.derby.iapi.error.PublicAPI;
34 import org.apache.derby.iapi.error.StandardException;
35
36 import java.util.Stack JavaDoc;
37 import java.util.Hashtable JavaDoc;
38 import java.util.Properties JavaDoc;
39
40 import java.io.InputStream JavaDoc;
41 import java.io.FileInputStream JavaDoc;
42 import java.io.BufferedInputStream JavaDoc;
43 import java.io.FileNotFoundException JavaDoc;
44 import java.io.StringReader JavaDoc;
45 import java.sql.DriverManager JavaDoc;
46 import java.sql.Driver JavaDoc;
47 import java.sql.Connection JavaDoc;
48 import java.sql.SQLException JavaDoc;
49 import java.sql.ResultSet JavaDoc;
50 import java.sql.Statement JavaDoc;
51 import java.sql.PreparedStatement JavaDoc;
52
53 import java.lang.reflect.*;
54
55 /**
56     This class is utilities specific to the two ij Main's.
57     This factoring enables sharing the functionality for
58     single and dual connection ij runs.
59
60     @author jerry
61  */

62 public class utilMain implements java.security.PrivilegedAction JavaDoc {
63
64   private static final Class JavaDoc[] CONN_PARAM = { Integer.TYPE };
65   private static final Object JavaDoc[] CONN_ARG = { new Integer JavaDoc(JDBC30Translation.CLOSE_CURSORS_AT_COMMIT)};
66
67     private StatementFinder[] commandGrabber;
68     UCode_CharStream charStream;
69     ijTokenManager ijTokMgr;
70     ij ijParser;
71     ConnectionEnv[] connEnv;
72     private int currCE;
73     private final int numConnections;
74     private boolean fileInput;
75     private boolean initialFileInput;
76     private boolean mtUse;
77     private boolean firstRun = true;
78     private LocalizedOutput out = null;
79     private Properties JavaDoc connAttributeDefaults;
80     private Hashtable JavaDoc ignoreErrors;
81     /**
82      * True if to display the error code when
83      * displaying a SQLException.
84      */

85     private final boolean showErrorCode;
86     
87     /**
88      * Value of the system property ij.execptionTrace
89      */

90     private final String JavaDoc ijExceptionTrace;
91
92     protected boolean isJCC; //The driver being used is JCC
93

94     /*
95         In the goodness of time, this could be an ij property
96      */

97     public static final int BUFFEREDFILESIZE = 2048;
98
99     /*
100      * command can be redirected, so we stack up command
101      * grabbers as needed.
102      */

103     Stack JavaDoc oldGrabbers = new Stack JavaDoc();
104
105     LocalizedResource langUtil = LocalizedResource.getInstance();
106     /**
107      * Set up the test to run with 'numConnections' connections/users.
108      *
109      * @param numConnections The number of connections/users to test.
110      */

111     utilMain(int numConnections, LocalizedOutput out)
112         throws ijFatalException
113     {
114         this(numConnections, out, (Hashtable JavaDoc)null);
115     }
116
117     /**
118      * Set up the test to run with 'numConnections' connections/users.
119      *
120      * @param numConnections The number of connections/users to test.
121      * @param ignoreErrors A list of errors to ignore. If null,
122      * all errors are printed out and nothing
123      * is fatal. If non-null, if an error is
124      * hit and it is in this list, it is silently
125      * ignore. Otherwise, an ijFatalException is
126      * thrown. ignoreErrors is used for stress
127      * tests.
128      */

129     public utilMain(int numConnections, LocalizedOutput out, Hashtable JavaDoc ignoreErrors)
130         throws ijFatalException
131     {
132         String JavaDoc framework_property = util.getSystemProperty("framework");
133         
134         if (framework_property != null)
135         {
136             if (framework_property.equals("DB2jNet")
137                     || framework_property.equals("DB2jcc"))
138                 isJCC = true;
139         }
140         /* init the parser; give it no input to start with.
141          * (1 parser for entire test.)
142          */

143         charStream = new UCode_CharStream(
144                         new StringReader JavaDoc(" "), 1, 1);
145         ijTokMgr = new ijTokenManager(charStream);
146         ijParser = new ij(ijTokMgr, this);
147         this.out = out;
148         this.ignoreErrors = ignoreErrors;
149         
150         showErrorCode =
151             Boolean.valueOf(
152                     util.getSystemProperty("ij.showErrorCode")
153                     ).booleanValue();
154         
155         ijExceptionTrace = util.getSystemProperty("ij.exceptionTrace");
156
157         this.numConnections = numConnections;
158         /* 1 StatementFinder and ConnectionEnv per connection/user. */
159         commandGrabber = new StatementFinder[numConnections];
160         connEnv = new ConnectionEnv[numConnections];
161
162         for (int ictr = 0; ictr < numConnections; ictr++)
163         {
164             commandGrabber[ictr] = new StatementFinder(langUtil.getNewInput(System.in));
165             connEnv[ictr] = new ConnectionEnv(ictr, (numConnections > 1), (numConnections == 1));
166         }
167
168         /* Start with connection/user 0 */
169         currCE = 0;
170         fileInput = false;
171         initialFileInput = false;
172         firstRun = true;
173     }
174     
175     /**
176      * Initialize the connections from the environment.
177      *
178      */

179     public void initFromEnvironment()
180     {
181         ijParser.initFromEnvironment();
182         
183         for (int ictr = 0; ictr < numConnections; ictr++)
184         {
185             try {
186                 connEnv[ictr].init(out);
187             } catch (SQLException JavaDoc s) {
188                 JDBCDisplayUtil.ShowException(out, s); // will continue past connect failure
189
} catch (ClassNotFoundException JavaDoc c) {
190                 JDBCDisplayUtil.ShowException(out, c); // will continue past driver failure
191
} catch (InstantiationException JavaDoc i) {
192                 JDBCDisplayUtil.ShowException(out, i); // will continue past driver failure
193
} catch (IllegalAccessException JavaDoc ia) {
194                 JDBCDisplayUtil.ShowException(out, ia); // will continue past driver failure
195
}
196         }
197     }
198
199
200     /**
201      * run ij over the specified input, sending output to the
202      * specified output. Any prior input and output will be lost.
203      *
204      * @param in source for input to ij
205      * @param out sink for output from ij
206      * @param connAttributeDefaults connection attributes from -ca ij arg
207      */

208     public void go(LocalizedInput[] in, LocalizedOutput out,
209                    Properties JavaDoc connAttributeDefaults) throws ijFatalException
210     {
211         this.out = out;
212         this.connAttributeDefaults = connAttributeDefaults;
213         
214         ijParser.setConnection(connEnv[currCE], (numConnections > 1));
215         fileInput = initialFileInput = (!in[currCE].isStandardInput());
216
217         for (int ictr = 0; ictr < commandGrabber.length; ictr++) {
218             commandGrabber[ictr].ReInit(in[ictr]);
219         }
220
221         if (firstRun) {
222
223             // figure out which version this is
224
InputStream JavaDoc versionStream = (InputStream JavaDoc) java.security.AccessController.doPrivileged(this);
225
226             // figure out which version this is
227
ProductVersionHolder ijVersion =
228                 ProductVersionHolder.getProductVersionHolderFromMyEnv(versionStream);
229
230             String JavaDoc version;
231             if (ijVersion != null)
232             {
233                 version = "" + ijVersion.getMajorVersion() + "." +
234                     ijVersion.getMinorVersion();
235             }
236             else
237             {
238                 version = "?";
239             }
240
241             out.println(langUtil.getTextMessage("IJ_IjVers30C199", version));
242             for (int i=connEnv.length-1;i>=0;i--) { // print out any initial warnings...
243
Connection JavaDoc c = connEnv[i].getConnection();
244                 if (c!=null) {
245                     JDBCDisplayUtil.ShowWarnings(out,c);
246                 }
247             }
248             firstRun = false;
249
250             //check if the property is set to not show select count and set the static variable
251
//accordingly.
252
boolean showNoCountForSelect = Boolean.getBoolean("ij.showNoCountForSelect");
253             JDBCDisplayUtil.showSelectCount = !showNoCountForSelect;
254
255             //check if the property is set to not show initial connections and accordingly set the
256
//static variable.
257
boolean showNoConnectionsAtStart = Boolean.getBoolean("ij.showNoConnectionsAtStart");
258             if (!(showNoConnectionsAtStart)) {
259                 try {
260                     ijResult result = ijParser.showConnectionsMethod(true);
261                     displayResult(out,result,connEnv[currCE].getConnection());
262                 } catch (SQLException JavaDoc ex) {
263                     handleSQLException(out,ex);
264                 }
265             }
266         }
267         this.out = out;
268         runScriptGuts();
269         cleanupGo(in);
270     }
271     
272     /**
273      * Support to run a script. Performs minimal setup
274      * to set the passed in connection into the existing
275      * ij setup, ConnectionEnv.
276      * @param conn
277      * @param in
278      */

279     public int goScript(Connection JavaDoc conn,
280             LocalizedInput in)
281     {
282         JDBCDisplayUtil.showSelectCount = false;
283         connEnv[0].addSession(conn, (String JavaDoc) null);
284         fileInput = initialFileInput = !in.isStandardInput();
285         commandGrabber[0].ReInit(in);
286         return runScriptGuts();
287     }
288     
289     /**
290      * Run the guts of the script. Split out to allow
291      * calling from the full ij and the minimal goScript.
292      * @return The number of errors seen in the script.
293      *
294      */

295     private int runScriptGuts() {
296
297         int scriptErrorCount = 0;
298         
299         boolean done = false;
300         String JavaDoc command = null;
301         while (!ijParser.exit && !done) {
302             try{
303                 ijParser.setConnection(connEnv[currCE], (numConnections > 1));
304             } catch(Throwable JavaDoc t){
305                 //do nothing
306
}
307
308             connEnv[currCE].doPrompt(true, out);
309             try {
310                 command = null;
311                 out.flush();
312                 command = commandGrabber[currCE].nextStatement();
313
314                 // if there is no next statement,
315
// pop back to the top saved grabber.
316
while (command == null && ! oldGrabbers.empty()) {
317                     // close the old input file if not System.in
318
if (fileInput) commandGrabber[currCE].close();
319                     commandGrabber[currCE] = (StatementFinder)oldGrabbers.pop();
320                     if (oldGrabbers.empty())
321                         fileInput = initialFileInput;
322                     command = commandGrabber[currCE].nextStatement();
323                 }
324
325                 // if there are no grabbers left,
326
// we are done.
327
if (command == null && oldGrabbers.empty()) {
328                     done = true;
329                 }
330                 else {
331                     boolean elapsedTimeOn = ijParser.getElapsedTimeState();
332                     long beginTime = 0;
333                     long endTime;
334
335                     if (fileInput) {
336                         out.println(command+";");
337                         out.flush();
338                     }
339
340                     charStream.ReInit(new StringReader JavaDoc(command), 1, 1);
341                     ijTokMgr.ReInit(charStream);
342                     ijParser.ReInit(ijTokMgr);
343
344                     if (elapsedTimeOn) {
345                         beginTime = System.currentTimeMillis();
346                     }
347
348                     ijResult result = ijParser.ijStatement();
349                     displayResult(out,result,connEnv[currCE].getConnection());
350
351                     // if something went wrong, an SQLException or ijException was thrown.
352
// we can keep going to the next statement on those (see catches below).
353
// ijParseException means we try the SQL parser.
354

355                     /* Print the elapsed time if appropriate */
356                     if (elapsedTimeOn) {
357                         endTime = System.currentTimeMillis();
358                         out.println(langUtil.getTextMessage("IJ_ElapTime0Mil",
359                         langUtil.getNumberAsString(endTime - beginTime)));
360                     }
361
362                     // would like when it completes a statement
363
// to see if there is stuff after the ;
364
// and before the <EOL> that we will IGNORE
365
// (with a warning to that effect)
366
}
367
368                 } catch (ParseException e) {
369                     if (command != null)
370                         scriptErrorCount += doCatch(command) ? 0 : 1;
371                 } catch (TokenMgrError e) {
372                     if (command != null)
373                         scriptErrorCount += doCatch(command) ? 0 : 1;
374                 } catch (SQLException JavaDoc e) {
375                     scriptErrorCount++;
376                     // SQL exception occurred in ij's actions; print and continue
377
// unless it is considered fatal.
378
handleSQLException(out,e);
379                 } catch (ijException e) {
380                     scriptErrorCount++;
381                     // exception occurred in ij's actions; print and continue
382
out.println(langUtil.getTextMessage("IJ_IjErro0",e.getMessage()));
383                     doTrace(e);
384                 } catch (Throwable JavaDoc e) {
385                     scriptErrorCount++;
386                     out.println(langUtil.getTextMessage("IJ_JavaErro0",e.toString()));
387                     doTrace(e);
388                 }
389
390             /* Go to the next connection/user, if there is one */
391             currCE = ++currCE % connEnv.length;
392         }
393         
394         return scriptErrorCount;
395     }
396     
397     /**
398      * Perform cleanup after a script has been run.
399      * Close the input streams if required and shutdown
400      * derby on an exit.
401      * @param in
402      */

403     private void cleanupGo(LocalizedInput[] in) {
404
405         // we need to close all sessions when done; otherwise we have
406
// a problem when a single VM runs successive IJ threads
407
try {
408             for (int i = 0; i < connEnv.length; i++) {
409                 connEnv[i].removeAllSessions();
410             }
411         } catch (SQLException JavaDoc se ) {
412             handleSQLException(out,se);
413         }
414         // similarly must close input files
415
for (int i = 0; i < numConnections; i++) {
416             try {
417                 in[i].close();
418             } catch (Exception JavaDoc e ) {
419                     out.println(langUtil.getTextMessage("IJ_CannotCloseInFile",
420                     e.toString()));
421             }
422         }
423
424         /*
425             If an exit was requested, then we will be shutting down.
426          */

427         if (ijParser.exit || (initialFileInput && !mtUse)) {
428             Driver JavaDoc d = null;
429             try {
430                 d = DriverManager.getDriver("jdbc:derby:");
431             } catch (Throwable JavaDoc e) {
432                 d = null;
433             }
434             if (d!=null) { // do we have a driver running? shutdown on exit.
435
try {
436                     DriverManager.getConnection("jdbc:derby:;shutdown=true");
437                 } catch (SQLException JavaDoc e) {
438                     // ignore the errors, they are expected.
439
}
440             }
441         }
442     }
443
444     private void displayResult(LocalizedOutput out, ijResult result, Connection JavaDoc conn) throws SQLException JavaDoc {
445         // display the result, if appropriate.
446
if (result!=null) {
447             if (result.isConnection()) {
448                 if (result.hasWarnings()) {
449                     JDBCDisplayUtil.ShowWarnings(out,result.getSQLWarnings());
450                     result.clearSQLWarnings();
451                 }
452             } else if (result.isStatement()) {
453                 Statement JavaDoc s = result.getStatement();
454                 try {
455                     JDBCDisplayUtil.DisplayResults(out,s,connEnv[currCE].getConnection());
456                 } catch (SQLException JavaDoc se) {
457                     result.closeStatement();
458                     throw se;
459                 }
460                 result.closeStatement();
461             } else if (result.isNextRowOfResultSet()) {
462                 ResultSet JavaDoc r = result.getNextRowOfResultSet();
463                 JDBCDisplayUtil.DisplayCurrentRow(out,r,connEnv[currCE].getConnection());
464             } else if (result.isVector()) {
465                 util.DisplayVector(out,result.getVector());
466                 if (result.hasWarnings()) {
467                     JDBCDisplayUtil.ShowWarnings(out,result.getSQLWarnings());
468                     result.clearSQLWarnings();
469                 }
470             } else if (result.isMulti()) {
471                 try {
472                     util.DisplayMulti(out,(PreparedStatement JavaDoc)result.getStatement(),result.getResultSet(),connEnv[currCE].getConnection());
473                 } catch (SQLException JavaDoc se) {
474                     result.closeStatement();
475                     throw se;
476                 }
477                 result.closeStatement(); // done with the statement now
478
if (result.hasWarnings()) {
479                     JDBCDisplayUtil.ShowWarnings(out,result.getSQLWarnings());
480                     result.clearSQLWarnings();
481                 }
482             } else if (result.isResultSet()) {
483                 ResultSet JavaDoc rs = result.getResultSet();
484                 try {
485                     JDBCDisplayUtil.DisplayResults(out,rs,connEnv[currCE].getConnection(), result.getColumnDisplayList(), result.getColumnWidthList());
486                 } catch (SQLException JavaDoc se) {
487                     result.closeStatement();
488                     throw se;
489                 }
490                 result.closeStatement();
491             } else if (result.isException()) {
492                 JDBCDisplayUtil.ShowException(out,result.getException());
493             }
494         }
495     }
496
497     /**
498      * catch processing on failed commands. This really ought to
499      * be in ij somehow, but it was easier to catch in Main.
500      */

501     private boolean doCatch(String JavaDoc command) {
502         // this retries the failed statement
503
// as a JSQL statement; it uses the
504
// ijParser since that maintains our
505
// connection and state.
506

507         
508         try {
509             boolean elapsedTimeOn = ijParser.getElapsedTimeState();
510             long beginTime = 0;
511             long endTime;
512
513             if (elapsedTimeOn) {
514                 beginTime = System.currentTimeMillis();
515             }
516
517             ijResult result = ijParser.executeImmediate(command);
518             displayResult(out,result,connEnv[currCE].getConnection());
519
520             /* Print the elapsed time if appropriate */
521             if (elapsedTimeOn) {
522                 endTime = System.currentTimeMillis();
523                 out.println(langUtil.getTextMessage("IJ_ElapTime0Mil_4",
524                 langUtil.getNumberAsString(endTime - beginTime)));
525             }
526             return true;
527
528         } catch (SQLException JavaDoc e) {
529             // SQL exception occurred in ij's actions; print and continue
530
// unless it is considered fatal.
531
handleSQLException(out,e);
532         } catch (ijException i) {
533             out.println(langUtil.getTextMessage("IJ_IjErro0_5", i.getMessage()));
534             doTrace(i);
535         } catch (ijTokenException ie) {
536             out.println(langUtil.getTextMessage("IJ_IjErro0_6", ie.getMessage()));
537             doTrace(ie);
538         } catch (Throwable JavaDoc t) {
539             out.println(langUtil.getTextMessage("IJ_JavaErro0_7", t.toString()));
540             doTrace(t);
541         }
542         return false;
543     }
544
545     /**
546      * This routine displays SQL exceptions and decides whether they
547      * are fatal or not, based on the ignoreErrors field. If they
548      * are fatal, an ijFatalException is thrown.
549      * Lifted from ij/util.java:ShowSQLException
550      */

551     private void handleSQLException(LocalizedOutput out, SQLException JavaDoc e)
552         throws ijFatalException
553     {
554         String JavaDoc errorCode;
555         String JavaDoc sqlState = null;
556         SQLException JavaDoc fatalException = null;
557
558         if (showErrorCode) {
559             errorCode = langUtil.getTextMessage("IJ_Erro0",
560             langUtil.getNumberAsString(e.getErrorCode()));
561         }
562         else {
563             errorCode = "";
564         }
565
566         for (; e!=null; e=e.getNextException())
567         {
568             /*
569             ** If we are to throw errors, then throw the exceptions
570             ** that aren't in the ignoreErrors list. If
571             ** the ignoreErrors list is null we don't throw
572             ** any errors.
573             */

574             if (ignoreErrors != null)
575             {
576                 sqlState = e.getSQLState();
577                 if ((sqlState != null) &&
578                     (ignoreErrors.get(sqlState) != null))
579                 {
580                     continue;
581                 }
582                 else
583                 {
584                     fatalException = e;
585                 }
586             }
587
588             String JavaDoc st1 = JDBCDisplayUtil.mapNull(e.getSQLState(),langUtil.getTextMessage("IJ_NoSqls"));
589             String JavaDoc st2 = JDBCDisplayUtil.mapNull(e.getMessage(),langUtil.getTextMessage("IJ_NoMess"));
590             out.println(langUtil.getTextMessage("IJ_Erro012", st1, st2, errorCode));
591             doTrace(e);
592         }
593         if (fatalException != null)
594         {
595             throw new ijFatalException(fatalException);
596         }
597     }
598
599     /**
600      * stack trace dumper
601      */

602     private void doTrace(Throwable JavaDoc t) {
603         if (ijExceptionTrace != null) {
604             t.printStackTrace(out);
605         }
606         out.flush();
607     }
608
609     void newInput(String JavaDoc fileName) {
610         FileInputStream JavaDoc newFile = null;
611         try {
612             newFile = new FileInputStream JavaDoc(fileName);
613         } catch (FileNotFoundException JavaDoc e) {
614             throw ijException.fileNotFound();
615         }
616         if (newFile == null) return;
617
618         // if the file was opened, move to use it for input.
619
oldGrabbers.push(commandGrabber[currCE]);
620         commandGrabber[currCE] =
621                 new StatementFinder(langUtil.getNewInput(new BufferedInputStream JavaDoc(newFile, BUFFEREDFILESIZE)));
622         fileInput = true;
623     }
624
625     void newResourceInput(String JavaDoc resourceName) {
626         InputStream JavaDoc is = util.getResourceAsStream(resourceName);
627         if (is==null) throw ijException.resourceNotFound();
628         oldGrabbers.push(commandGrabber[currCE]);
629         commandGrabber[currCE] =
630                 new StatementFinder(langUtil.getNewEncodedInput(new BufferedInputStream JavaDoc(is, BUFFEREDFILESIZE), "UTF8"));
631         fileInput = true;
632     }
633
634     /**
635      * REMIND: eventually this might be part of StatementFinder,
636      * used at each carriage return to show that it is still "live"
637      * when it is reading multi-line input.
638      */

639     static void doPrompt(boolean newStatement, LocalizedOutput out, String JavaDoc tag)
640      {
641         if (newStatement) {
642             out.print("ij"+(tag==null?"":tag)+"> ");
643         }
644         else {
645             out.print("> ");
646         }
647         out.flush();
648     }
649
650     void setMtUse(boolean b) {
651         mtUse = b;
652     }
653
654     // JDBC 2.0 support
655

656
657     /**
658      * Connections by default create ResultSet objects with holdability true. This method can be used
659      * to change the holdability of the connection by passing one of ResultSet.HOLD_CURSORS_OVER_COMMIT
660      * or ResultSet.CLOSE_CURSORS_AT_COMMIT. We implement this using reflection in jdk13 and lower
661      *
662      * @param conn The connection.
663      * @param holdType The new holdability for the Connection object.
664      *
665      * @return The connection object with holdability set to passed value.
666      */

667     Connection JavaDoc setHoldability(Connection JavaDoc conn, int holdType)
668         throws SQLException JavaDoc
669     {
670     //Prior to db2 compatibility work, the default holdability for connections was close cursors over commit and all the tests
671
//were written based on that assumption
672
//Later, as part of db2 compatibility, we changed the default holdability for connection to hold cursors over commit.
673
//But in order for the existing tests to work fine, the tests needed a way to set the holdability to close cursors for connections
674
//Since there is no direct jdbc api in jdk13 and lower to do that, we are using reflection to set the holdability to close cursors
675
try { //for jdks prior to jdk14, need to use reflection to set holdability to false.
676
Method sh = conn.getClass().getMethod("setHoldability", CONN_PARAM);
677         sh.invoke(conn, CONN_ARG);
678     } catch( Exception JavaDoc e) {
679         throw PublicAPI.wrapStandardException( StandardException.plainWrapException( e));
680     }
681     return conn;
682     }
683
684     /**
685      * Retrieves the current holdability of ResultSet objects created using this
686      * Connection object. We implement this using reflection in jdk13 and lower
687      *
688      * @return The holdability, one of ResultSet.HOLD_CURSORS_OVER_COMMIT
689      * or ResultSet.CLOSE_CURSORS_AT_COMMIT
690      *
691      */

692     int getHoldability(Connection JavaDoc conn)
693         throws SQLException JavaDoc
694     {
695     //this method is used to make sure we are not trying to create a statement with holdability different than the connection holdability
696
//This is because jdk13 and lower does not have support for that.
697
//The holdability of connection and statement can differ if connection holdability is set to close cursor on commit using reflection
698
//and statement is getting created with holdability true
699
//Another instance of holdability of connection and statement not being same is when connection holdability is hold cursor
700
//over commit and statement is being created with holdability false
701
int defaultHoldability = JDBC30Translation.HOLD_CURSORS_OVER_COMMIT;
702     try {
703         Method sh = conn.getClass().getMethod("getHoldability", null);
704         defaultHoldability = ((Integer JavaDoc)sh.invoke(conn, null)).intValue();
705     } catch( Exception JavaDoc e) {
706         throw PublicAPI.wrapStandardException( StandardException.plainWrapException( e));
707     }
708     return defaultHoldability;
709     }
710
711     /**
712      * Create the right kind of statement (scrolling or not)
713      * off of the specified connection.
714      *
715      * @param conn The connection.
716      * @param scrollType The scroll type of the cursor.
717      *
718      * @return The statement.
719      */

720     Statement JavaDoc createStatement(Connection JavaDoc conn, int scrollType, int holdType)
721         throws SQLException JavaDoc
722     {
723         //following if is used to make sure we are not trying to create a statement with holdability different that the connection
724
//holdability. This is because jdk13 and lower does not have support for that.
725
//The holdability of connection and statement can differ if connection holdability is set to close cursor on commit using reflection
726
//and statement is getting created with holdability true
727
//Another instance of holdability of connection and statement not being same is when connection holdability is hold cursor
728
//over commit and statement is being created with holdability false
729
if (holdType != getHoldability(conn))
730         {
731             throw ijException.holdCursorsNotSupported();
732         }
733       
734         Statement JavaDoc stmt;
735         try {
736             stmt = conn.createStatement(scrollType, JDBC20Translation.CONCUR_READ_ONLY);
737         } catch(AbstractMethodError JavaDoc ame) {
738         //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
739
//to jdbc 1.x functionality
740
stmt = conn.createStatement();
741         }
742         return stmt;
743     }
744
745     /**
746      * Position on the specified row of the specified ResultSet.
747      *
748      * @param rs The specified ResultSet.
749      * @param row The row # to move to.
750      * (Negative means from the end of the result set.)
751      *
752      * @return NULL.
753      *
754      * @exception SQLException thrown on error.
755      * (absolute() not supported pre-JDBC2.0)
756      */

757     ijResult absolute(ResultSet JavaDoc rs, int row)
758         throws SQLException JavaDoc
759     {
760         boolean forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
761
762         if (forwardOnly)
763         {
764             throw ijException.forwardOnlyCursor("ABSOLUTE");
765         }
766
767         // 0 is an *VALID* value for row
768
return new ijRowResult(rs, rs.absolute(row));
769     }
770
771     /**
772      * Move the cursor position by the specified amount.
773      *
774      * @param rs The specified ResultSet.
775      * @param row The # of rows to move.
776      * (Negative means toward the beginning of the result set.)
777      *
778      * @return NULL.
779      *
780      * @exception SQLException thrown on error.
781      * (relative() not supported pre-JDBC2.0)
782      */

783     ijResult relative(ResultSet JavaDoc rs, int row)
784         throws SQLException JavaDoc
785     {
786         boolean forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
787
788         // relative is only allowed on scroll cursors
789
if (forwardOnly)
790         {
791             throw ijException.forwardOnlyCursor("RELATIVE");
792         }
793
794         return new ijRowResult(rs, rs.relative(row));
795     }
796
797     /**
798      * Position before the first row of the specified ResultSet
799      * and return NULL to the user.
800      *
801      * @param rs The specified ResultSet.
802      *
803      * @return NULL.
804      *
805      * @exception SQLException thrown on error.
806      * (beforeFirst() not supported pre-JDBC2.0)
807      */

808     ijResult beforeFirst(ResultSet JavaDoc rs)
809         throws SQLException JavaDoc
810     {
811         boolean forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
812
813         // before first is only allowed on scroll cursors
814
if (forwardOnly)
815         {
816             throw ijException.forwardOnlyCursor("BEFORE FIRST");
817         }
818
819         rs.beforeFirst();
820         return new ijRowResult(rs, false);
821     }
822
823     /**
824      * Position on the first row of the specified ResultSet
825      * and return that row to the user.
826      *
827      * @param rs The specified ResultSet.
828      *
829      * @return The first row of the ResultSet.
830      *
831      * @exception SQLException thrown on error.
832      * (first() not supported pre-JDBC2.0)
833      */

834     ijResult first(ResultSet JavaDoc rs)
835         throws SQLException JavaDoc
836     {
837         boolean forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
838
839         // first is only allowed on scroll cursors
840
if (forwardOnly)
841         {
842             throw ijException.forwardOnlyCursor("FIRST");
843         }
844
845         return new ijRowResult(rs, rs.first());
846     }
847
848     /**
849      * Position after the last row of the specified ResultSet
850      * and return NULL to the user.
851      *
852      * @param rs The specified ResultSet.
853      *
854      * @return NULL.
855      *
856      * @exception SQLException thrown on error.
857      * (afterLast() not supported pre-JDBC2.0)
858      */

859     ijResult afterLast(ResultSet JavaDoc rs)
860         throws SQLException JavaDoc
861     {
862         boolean forwardOnly;
863         try {
864             forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
865         } catch (AbstractMethodError JavaDoc ame) {
866         //because weblogic 4.5 doesn't yet implement jdbc 2.0 interfaces, need to go back
867
//to jdbc 1.x functionality
868
forwardOnly = true;
869         }
870         // after last is only allowed on scroll cursors
871
if (forwardOnly)
872         {
873             throw ijException.forwardOnlyCursor("AFTER LAST");
874         }
875
876         rs.afterLast();
877         return new ijRowResult(rs, false);
878     }
879
880     /**
881      * Position on the last row of the specified ResultSet
882      * and return that row to the user.
883      *
884      * @param rs The specified ResultSet.
885      *
886      * @return The last row of the ResultSet.
887      *
888      * @exception SQLException thrown on error.
889      * (last() not supported pre-JDBC2.0)
890      */

891     ijResult last(ResultSet JavaDoc rs)
892         throws SQLException JavaDoc
893     {
894         boolean forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
895
896         // last is only allowed on scroll cursors
897
if (forwardOnly)
898         {
899             throw ijException.forwardOnlyCursor("LAST");
900         }
901
902         return new ijRowResult(rs, rs.last());
903     }
904
905     /**
906      * Position on the previous row of the specified ResultSet
907      * and return that row to the user.
908      *
909      * @param rs The specified ResultSet.
910      *
911      * @return The previous row of the ResultSet.
912      *
913      * @exception SQLException thrown on error.
914      * (previous() not supported pre-JDBC2.0)
915      */

916     ijResult previous(ResultSet JavaDoc rs)
917         throws SQLException JavaDoc
918     {
919         boolean forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
920  
921         // first is only allowed on scroll cursors
922
if (forwardOnly)
923         {
924             throw ijException.forwardOnlyCursor("PREVIOUS");
925         }
926
927         return new ijRowResult(rs, rs.previous());
928     }
929
930     /**
931      * Get the current row number
932      *
933      * @param rs The specified ResultSet.
934      *
935      * @return The current row number
936      *
937      * @exception SQLException thrown on error.
938      * (getRow() not supported pre-JDBC2.0)
939      */

940     int getCurrentRowNumber(ResultSet JavaDoc rs)
941         throws SQLException JavaDoc
942     {
943
944         boolean forwardOnly = (rs.getStatement().getResultSetType() == JDBC20Translation.TYPE_FORWARD_ONLY);
945
946         // getCurrentRow is only allowed on scroll cursors
947
if (forwardOnly)
948         {
949             throw ijException.forwardOnlyCursor("GETCURRENTROWNUMBER");
950         }
951
952         return rs.getRow();
953     }
954
955     Properties JavaDoc getConnAttributeDefaults ()
956     {
957         return connAttributeDefaults;
958     }
959
960     public final Object JavaDoc run() {
961         return getClass().getResourceAsStream(ProductGenusNames.TOOLS_INFO);
962     }
963 }
964
Popular Tags