// This example is from _Java Examples in a Nutshell_. (http://www.oreilly.com) // Copyright (c) 1997 by David Flanagan // This example is provided WITHOUT ANY WARRANTY either expressed or implied. // You may study, use, modify, and distribute it for non-commercial purposes. // For any commercial use, see http://www.davidflanagan.com/javaexamples 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 properties 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, using defaults if not found. // These defaults will probably not work for you! String driver = p.getProperty("driver", "postgres95.PGDriver"); String database = p.getProperty("database","jdbc:postgres95:///APIDB"); String user = p.getProperty("user", ""); String password = p.getProperty("password", ""); // 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 extra 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 ] 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 int isField = r.getInt(4); // is the member a field? // Display this match System.out.println(pkg + "." + cls + "." + member + ((isField==1)?"":"()")); } // 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 of the name. // Note the use of the SQL LIKE keyword and % wildcard characters s.executeQuery("SELECT name FROM package " + "WHERE 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 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(); } }