// 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 <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
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();
}
}
|