18.4 Using the API Database

Example 18-4 displays a program, LookupAPI, that uses the database built by the MakeAPIDB program of Example 18-3 and makes interesting SQL queries against it. LookupAPI behaves as follows:

  • When invoked with the name of a class member, it lists the full name (including package and class) of each field and/or method that has that name.

  • When run with the name of a class, it lists the full name of every class in any package that has that name.

  • When called with a portion of a package name, it lists the names of all the packages that contain that string.

  • When invoked with the -l option and a class name, it lists every member of every class that has that name.

  • When run with the -l option and a portion of a package name, it lists all the classes and interfaces in any package that matches that string.

LookupAPI reads the same APIDB.props property file MakeAPIDB does. Or, alternatively, it reads a property file specified on the command line following a -p flag. Using the database connection parameters in the property file, the program connects to a database and executes the necessary SQL queries to return the desired information. Note that it calls the setReadOnly( ) method of the Connection object. Doing this provides a hint that the program performs only queries and doesn't modify the database in any way. For some database systems, this may improve efficiency. Other than the setReadOnly( ) method, this example doesn't introduce any new JDBC features. It simply serves as a real-world application of a database and demonstrates some of the powerful database queries that can be expressed using SQL.

Example 18-4. LookupAPI.java
package je3.sql; import java.sql.*; import java.io.FileInputStream; import java.util.Properties; /**  * This program uses the database created by MakeAPIDB.  It opens a connection  * to a database using the same property file used by MakeAPIDB.  Then it  * queries that database in several interesting ways to obtain useful   * information about Java APIs.  It can be used to look up the fully-qualified  * name of a member, class, or package, or it can be used to list the members  * of a class or package.  **/ public class LookupAPI {     public static void main(String[  ] args) {         Connection c = null;                // JDBC connection to the database         try {             // Some default values             String target = null;             // The name to look up             boolean list = false;             // List members or lookup name?             String propfile = "APIDB.props";  // The file of db parameters                          // Parse the command-line arguments             for(int i = 0; i < args.length; i++) {                 if (args[i].equals("-l")) list = true;                 else if (args[i].equals("-p")) propfile = args[++i];                 else if (target != null)                      throw new IllegalArgumentException("Unexpected argument: "                                                        + args[i]);                 else target = args[i];             }             if (target == null)                 throw new IllegalArgumentException("No target specified");             // Now determine the values needed to set up the database             // connection. The program attempts to read a property file             // named "APIDB.props", or optionally specified with the             // -p argument.  This property file may contain "driver",             // "database", "user", and "password" properties that             // specify the necessary values for connecting to the db.             // If the properties file does not exist, or does not             // contain the named properties, defaults will be used.             Properties p = new Properties( );               // Empty properties             try { p.load(new FileInputStream(propfile)); } // Try to load props             catch (Exception e) {  }             // Read values from Properties file             String driver = p.getProperty("driver");             String database = p.getProperty("database");             String user = p.getProperty("user", "");             String password = p.getProperty("password", "");             // The driver and database properties are mandatory             if (driver == null)                  throw new IllegalArgumentException("No driver specified!");             if (database == null)                  throw new IllegalArgumentException("No database specified!");             // Load the database driver             Class.forName(driver);             // And set up a connection to the specified database             c = DriverManager.getConnection(database, user, password);             // Tell it we will not do any updates.             // This hint may improve efficiency.             c.setReadOnly(true);             // If the "-l" option was given, then list the members of             // the named package or class.  Otherwise, lookup all             // matches for the specified member, class, or package.             if (list) list(c, target);             else lookup(c, target);         }         // If anything goes wrong, print the exception and a usage message.  If         // a SQLException is thrown, display the state message it includes.         catch (Exception e) {             System.out.println(e);             if (e instanceof SQLException)                  System.out.println(((SQLException) e).getSQLState( ));             System.out.println("Usage: java LookupAPI [-l] [-p <propfile>] " +                                "target");         }         // Always close the DB connection when we're done with it.         finally {             try { c.close( ); } catch (Exception e) {  }         }     }          /**      * This method looks up all matches for the specified target string in the      * database.  First, it prints the full name of any members by that name.      * Then it prints the full name of any classes by that name.  Then it       * prints the name of any packages that contain the specified name      **/     public static void lookup(Connection c, String target) throws SQLException     {         // Create the Statement object we'll use to query the database         Statement s = c.createStatement( );                  // Go find all class members with the specified name         s.executeQuery("SELECT DISTINCT " +                         "package.name, class.name, member.name, member.isField"+                        " FROM package, class, member" +                         " WHERE member.name='" + target + "'" +                        "   AND member.classId=class.id " +                        "   AND class.packageId=package.id");                  // Loop through the results, and print them out (if there are any).         ResultSet r = s.getResultSet( );         while(r.next( )) {             String pkg = r.getString(1);       // package name             String cls = r.getString(2);       // class name             String member = r.getString(3);    // member name             boolean isField = r.getBoolean(4); // is the member a field?             // Display this match             System.out.println(pkg + "." + cls + "." + member +                                 (isField?"":"( )"));         }                  // Now look for a class with the specified name         s.executeQuery("SELECT package.name, class.name " +                         "FROM package, class " +                         "WHERE class.name='" + target + "' " +                        "  AND class.packageId=package.id");         // Loop through the results and print them out         r = s.getResultSet( );         while(r.next( )) System.out.println(r.getString(1) + "." +                                            r.getString(2));                  // Finally, look for a package that matches a part of the name.         // Note the use of the SQL LIKE keyword and % wildcard characters         s.executeQuery("SELECT name FROM package " +                         "WHERE name='" + target + "'" +                        "   OR name LIKE '%." + target + ".%' " +                        "   OR name LIKE '" + target + ".%' " +                        "   OR name LIKE '%." + target + "'");         // Loop through the results and print them out         r = s.getResultSet( );         while(r.next( )) System.out.println(r.getString(1));                  // Finally, close the Statement object         s.close( );     }          /**      * This method looks for classes with the specified name, or packages      * that contain the specified name.  For each class it finds, it displays      * all methods and fields of the class.  For each package it finds, it      * displays all classes in the package.      **/     public static void list(Connection conn, String target) throws SQLException     {         // Create two Statement objects to query the database with         Statement s = conn.createStatement( );         Statement t = conn.createStatement( );                  // Look for a class with the given name         s.executeQuery("SELECT package.name, class.name " +                         "FROM package, class " +                         "WHERE class.name='" + target + "' " +                        "  AND class.packageId=package.id");         // Loop through all matches         ResultSet r = s.getResultSet( );         while(r.next( )) {             String p = r.getString(1);  // package name             String c = r.getString(2);  // class name             // Print out the matching class name             System.out.println("class " + p + "." + c + " {");                          // Now query all members of the class             t.executeQuery("SELECT DISTINCT member.name, member.isField " +                             "FROM package, class, member " +                             "WHERE package.name = '" + p + "' " +                            "  AND class.name = '" + c + "' " +                             "  AND member.classId=class.id " +                            "  AND class.packageId=package.id " +                            "ORDER BY member.isField, member.name");                          // Loop through the ordered list of all members, and print them out             ResultSet r2 = t.getResultSet( );             while(r2.next( )) {                 String m = r2.getString(1);                 int isField = r2.getInt(2);                 System.out.println("  " + m + ((isField == 1)?"":"( )"));             }             // End the class listing             System.out.println("}");         }                  // Now go look for a package that matches the specified name         s.executeQuery("SELECT name FROM package " +                        "WHERE name='" + target + "'" +                        "   OR name LIKE '%." + target + ".%' " +                        "   OR name LIKE '" + target + ".%' " +                        "   OR name LIKE '%." + target + "'");         // Loop through any matching packages         r = s.getResultSet( );         while(r.next( )) {             // Display the name of the package             String p = r.getString(1);             System.out.println("Package " + p + ": ");                          // Get a list of all classes and interfaces in the package             t.executeQuery("SELECT class.name FROM package, class " +                             "WHERE package.name='" + p + "' " +                            "  AND class.packageId=package.id " +                            "ORDER BY class.name");             // Loop through the list and print them out.             ResultSet r2 = t.getResultSet( );             while(r2.next( )) System.out.println("  " + r2.getString(1));         }                  // Finally, close both Statement objects         s.close( ); t.close( );     } }


Java Examples in a Nutshell
Java Examples in a Nutshell, 3rd Edition
ISBN: 0596006209
EAN: 2147483647
Year: 2003
Pages: 285

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net