KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > internetcds > jdbc > tds > Driver


1 //
2
// Copyright 1998 CDS Networks, Inc., Medford Oregon
3
//
4
// All rights reserved.
5
//
6
// Redistribution and use in source and binary forms, with or without
7
// modification, are permitted provided that the following conditions are met:
8
// 1. Redistributions of source code must retain the above copyright
9
// notice, this list of conditions and the following disclaimer.
10
// 2. Redistributions in binary form must reproduce the above copyright
11
// notice, this list of conditions and the following disclaimer in the
12
// documentation and/or other materials provided with the distribution.
13
// 3. All advertising materials mentioning features or use of this software
14
// must display the following acknowledgement:
15
// This product includes software developed by CDS Networks, Inc.
16
// 4. The name of CDS Networks, Inc. may not be used to endorse or promote
17
// products derived from this software without specific prior
18
// written permission.
19
//
20
// THIS SOFTWARE IS PROVIDED BY CDS NETWORKS, INC. ``AS IS'' AND
21
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23
// ARE DISCLAIMED. IN NO EVENT SHALL CDS NETWORKS, INC. BE LIABLE
24
// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25
// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26
// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29
// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30
// SUCH DAMAGE.
31
//
32

33
34
35 package com.internetcds.jdbc.tds;
36
37
38 import java.sql.*;
39 import java.util.*;
40 import com.internetcds.jdbc.tds.TdsException;
41
42
43
44 /**
45  * <P>The Java SQL framework allows for multiple database drivers.
46  *
47  * <P>Each driver should supply a class that implements
48  * the Driver interface.
49  *
50  * <P>The DriverManager will try to load as many drivers as it can
51  * find and then for any given connection request, it will ask each
52  * driver in turn to try to connect to the target URL.
53  *
54  * <P>It is strongly recommended that each Driver class should be
55  * small and standalone so that the Driver class can be loaded and
56  * queried without bringing in vast quantities of supporting code.
57  *
58  * <P>When a Driver class is loaded, it should create an instance of
59  * itself and register it with the DriverManager. This means that a
60  * user can load and register a driver by doing
61  * Class.forName("foo.bah.Driver").
62  *
63  * @author Craig Spannring
64  * @author Igor Petrovski
65  * @version $Id: Driver.java,v 1.1 2006/06/23 10:39:04 sinisa Exp $
66  *
67  * @see DriverManager
68  * @see Connection
69  */

70 public class Driver implements java.sql.Driver JavaDoc
71 {
72    public static final String JavaDoc cvsVersion = "$Id: Driver.java,v 1.1 2006/06/23 10:39:04 sinisa Exp $";
73    
74    
75    //
76
// Register ourselves with the DriverManager
77
//
78
static
79    {
80       try {
81          java.sql.DriverManager.registerDriver(new Driver());
82       }
83       catch (SQLException E) {
84          E.printStackTrace();
85       }
86    }
87    
88    
89    static final boolean debug = false;
90    static final String JavaDoc oldSQLServerUrlPrefix = "jdbc:freetds://";
91    static final String JavaDoc newSQLServerUrlPrefix = "jdbc:freetds:sqlserver://";
92    static final String JavaDoc sybaseUrlPrefix = "jdbc:freetds:sybase://";
93    static final String JavaDoc defaultSQLServerPort = "1433";
94    static final String JavaDoc defaultSybasePort = "7100";
95    
96
97
98    private boolean isValidHostname(String JavaDoc host)
99    {
100       return true; // XXX
101
}
102
103     /**
104      * Parses the properties specified in <i>url</i> and adds them to
105      * <i>result</i>.
106      *
107      * @return true if the URL could be parsed successfully.
108      */

109    protected boolean parseUrl(String JavaDoc url, Properties result)
110    {
111       String JavaDoc tmpUrl = url;
112       int serverType = -1;
113
114       if (tmpUrl.startsWith(oldSQLServerUrlPrefix) ||
115           tmpUrl.startsWith(newSQLServerUrlPrefix) ||
116           tmpUrl.startsWith(sybaseUrlPrefix))
117       {
118          if (tmpUrl.startsWith(oldSQLServerUrlPrefix))
119          {
120             serverType = Tds.SQLSERVER;
121             tmpUrl = tmpUrl.substring(oldSQLServerUrlPrefix.length());
122          }
123          else if (tmpUrl.startsWith(newSQLServerUrlPrefix))
124          {
125             serverType = Tds.SQLSERVER;
126             tmpUrl = tmpUrl.substring(newSQLServerUrlPrefix.length());
127          }
128          else if (tmpUrl.startsWith(sybaseUrlPrefix))
129          {
130             serverType = Tds.SYBASE;
131             tmpUrl = url.substring(sybaseUrlPrefix.length());
132          }
133
134          
135          try
136          {
137             StringTokenizer tokenizer = new StringTokenizer(tmpUrl, ":/;",
138                                                             true);
139             String JavaDoc tmp;
140             String JavaDoc host = null;
141             String JavaDoc port = (serverType==Tds.SYBASE
142                                  ? defaultSybasePort
143                                  : defaultSQLServerPort);
144             String JavaDoc database = null;
145 // String tdsVer = "42";
146
//Sinisa
147
String JavaDoc tdsVer = "7.0";
148
149             // Get the hostname
150
host = tokenizer.nextToken();
151
152
153             // Find the port if it has one.
154
tmp = tokenizer.nextToken();
155             if (tmp.equals(":"))
156             {
157                port = tokenizer.nextToken();
158                // Skip the '/' character
159
tmp = tokenizer.nextToken();
160             }
161
162             if (tmp.equals("/"))
163             {
164                // find the database name
165
database = tokenizer.nextToken();
166                if (tokenizer.hasMoreTokens())
167                   tmp = tokenizer.nextToken();
168             }
169
170
171             // XXX The next loop is a bit too permisive.
172
while (tmp.equals(";"))
173             {
174                // Extract the additional attribute.
175
String JavaDoc extra = tokenizer.nextToken();
176                StringTokenizer tok2 = new StringTokenizer(extra, "=", false);
177                String JavaDoc key = tok2.nextToken().toUpperCase();
178                if (tok2.hasMoreTokens())
179                {
180                    result.put(key, tok2.nextToken());
181                }
182
183                if (tokenizer.hasMoreTokens())
184                {
185                    tmp = tokenizer.nextToken();
186                }
187                else
188                {
189                    break;
190                }
191             }
192
193             // if there are anymore tokens then don't recognoze this URL
194
if ((! tokenizer.hasMoreTokens())
195                 && isValidHostname(host)
196                 && database!=null)
197             {
198                result.put("HOST", host);
199                result.put("SERVERTYPE", "" + serverType);
200                result.put("PORT", port);
201                result.put("DBNAME", database);
202             }
203             else
204             {
205                 return false;
206             }
207          }
208          catch (NoSuchElementException e)
209          {
210              return false;
211          }
212       }
213       else
214       {
215           return false;
216       }
217
218       return true;
219    }
220
221
222   /**
223    * Construct a new driver and register it with DriverManager
224    *
225    * @exception SQLException
226    */

227   public Driver() throws SQLException
228   {
229   }
230
231
232   /**
233    * Try to make a database connection to the given URL. The driver
234    * should return "null" if it realizes it is the wrong kind of
235    * driver to connect to the given URL. This will be common, as
236    * when the JDBC driverManager is asked to connect to a given URL,
237    * it passes the URL to each loaded driver in turn.
238    *
239    * <p>The driver should raise an SQLException if it is the right driver
240    * to connect to the given URL, but has trouble connecting to the
241    * database.
242    *
243    * <p>The java.util.Properties argument can be used to pass arbitrary
244    * string tag/value pairs as connection arguments.
245    *
246    * This driver handles URLs of the form:
247    * <PRE>
248    * jdbc:freetds://servername/database
249    * jdbc:freetds://servername:port/database
250    * jdbc:freetds:sqlserver://servername/database
251    * jdbc:freetds:sqlserver://servername:port/database
252    * jdbc:freetds:sybase://servername/database
253    * jdbc:freetds:sybase://servername:port/database
254    * </PRE>
255    * <p>
256    *
257    * <table><thead>Recognized Properties</thead>
258    * <tbody>
259    * <tr><td>PROGNAME<td>Send this name to server to identify the program</tr>
260    * <tr><td>APPNAME<td>Send this name to server to identify the app</tr>
261    * </tbody>
262    * </table>
263    *
264    * @param url the URL of the database to connect to
265    * @param info a list of arbitrary tag/value pairs as connection
266    * arguments
267    * @return a connection to the URL or null if it isnt us
268    * @exception SQLException if a database access error occurs
269    * @see java.sql.Driver#connect
270    */

271    public java.sql.Connection JavaDoc connect(String JavaDoc Url, Properties info)
272       throws SQLException
273    {
274       java.sql.Connection JavaDoc result = null;
275
276       if (!parseUrl(Url, info))
277       {
278          return null;
279       }
280       else
281       {
282          try
283          {
284              result = Constructors.newConnection(info);
285          }
286          catch(NumberFormatException JavaDoc e)
287          {
288             throw new SQLException("NumberFormatException converting port number");
289          }
290          catch(com.internetcds.jdbc.tds.TdsException e)
291          {
292             throw new SQLException(e.getMessage());
293          }
294       }
295       return result;
296    }
297
298   /**
299    * Returns true if the driver thinks it can open a connection to the
300    * given URL. Typically, drivers will return true if they understand
301    * the subprotocol specified in the URL and false if they don't. This
302    * driver's protocols start with jdbc:freetds:
303    *
304    * This driver handles URLs of the form:
305    * <PRE>
306    * jdbc:freetds://host:port/database
307    * </PRE>
308    * or
309    * <PRE>
310    * jdbc:freetds://host/database
311    * </PRE>
312    * <PRE>
313    * jdbc:freetds:sqlserver://host:port/database
314    * </PRE>
315    * or
316    * <PRE>
317    * jdbc:freetds:sqlserver://host/database
318    * </PRE>
319    * <PRE>
320    * jdbc:freetds:sybase://host:port/database
321    * </PRE>
322    * or
323    * <PRE>
324    * jdbc:freetds:sybase://host/database
325    * </PRE>
326    *
327    * @see java.sql.Driver#acceptsURL
328    * @param url the URL of the driver
329    * @return true if this driver accepts the given URL
330    * @exception SQLException if a database-access error occurs
331    */

332   public boolean acceptsURL(String JavaDoc url) throws SQLException
333   {
334      boolean result = parseUrl(url, new Properties());
335      return result;
336   }
337
338    /**
339     * <p>The getPropertyInfo method is intended to allow a generic GUI tool to
340     * discover what properties it should prompt a human for in order to get
341     * enough information to connect to a database. Note that depending on
342     * the values the human has supplied so far, additional values may become
343     * necessary, so it may be necessary to iterate though several calls
344     * to getPropertyInfo.
345     *
346     * @param url The URL of the database to connect to.
347     * @param info A proposed list of tag/value pairs that will be sent on
348     * connect open.
349     * @return An array of DriverPropertyInfo objects describing possible
350     * properties. This array may be an empty array if no properties
351     * are required.
352     * @exception SQLException if a database-access error occurs.
353     */

354    public DriverPropertyInfo[] getPropertyInfo(String JavaDoc Url, Properties Info)
355       throws SQLException
356    {
357       DriverPropertyInfo result[] = new DriverPropertyInfo[0];
358
359       return result;
360    }
361
362    /**
363     * Gets the drivers major version number
364     *
365     * @return the drivers major version number
366     */

367    public int getMajorVersion()
368    {
369       return DriverVersion.getDriverMajorVersion();
370    }
371
372
373    /**
374     * Get the driver's minor version number. Initially this should be 0.
375     */

376    public int getMinorVersion()
377    {
378       return DriverVersion.getDriverMinorVersion();
379    }
380
381
382    /**
383     * Report whether the Driver is a genuine JDBC COMPLIANT (tm) driver.
384     * A driver may only report "true" here if it passes the JDBC compliance
385     * tests, otherwise it is required to return false.
386     *
387     * JDBC compliance requires full support for the JDBC API and full support
388     * for SQL 92 Entry Level. It is expected that JDBC compliant drivers will
389     * be available for all the major commercial databases.
390     *
391     * This method is not intended to encourage the development of non-JDBC
392     * compliant drivers, but is a recognition of the fact that some vendors
393     * are interested in using the JDBC API and framework for lightweight
394     * databases that do not support full database functionality, or for
395     * special databases such as document information retrieval where a SQL
396     * implementation may not be feasible.
397     */

398    public boolean jdbcCompliant()
399    {
400       // :-( MS SQLServer 6.5 doesn't provide what JDBC wants.
401
// See DatabaseMetaData.nullPlusNonNullIsNull() for more details.
402
// XXX Need to check if Sybase could be jdbcCompliant
403
return false;
404    }
405
406 }
407
Popular Tags