sqlline.ClassNameCompleter Maven / Gradle / Ivy
/*
// Licensed to Julian Hyde under one or more contributor license
// agreements. See the NOTICE file distributed with this work for
// additional information regarding copyright ownership.
//
// Julian Hyde licenses this file to you under the Modified BSD License
// (the "License"); you may not use this file except in compliance with
// the License. You may obtain a copy of the License at:
//
// http://opensource.org/licenses/BSD-3-Clause
*/
package sqlline;
import java.io.*;
import java.net.*;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import jline.console.completer.StringsCompleter;
/**
* An implementation of {@link jline.console.completer.Completer} that completes
* java class names. By default, it scans the java class path to locate all the
* classes.
*/
public class ClassNameCompleter extends StringsCompleter {
/**
* Completes candidates using all the classes available in the
* java CLASSPATH.
*
* @throws IOException on error
*/
public ClassNameCompleter() throws IOException {
super(getClassNames());
getStrings().add(".");
}
public static Set getClassNames() throws IOException {
Set urls = new HashSet();
for (ClassLoader loader = ClassNameCompleter.class.getClassLoader();
loader != null;
loader = loader.getParent()) {
if (!(loader instanceof URLClassLoader)) {
continue;
}
Collections.addAll(urls, ((URLClassLoader) loader).getURLs());
}
// Now add the URL that holds java.lang.String. This is because
// some JVMs do not report the core classes jar in the list of
// class loaders.
Class[] systemClasses = {
String.class, javax.swing.JFrame.class
};
for (Class systemClass : systemClasses) {
URL classURL = systemClass.getResource(
"/" + systemClass.getName().replace('.', '/') + ".class");
if (classURL != null) {
URLConnection uc = classURL.openConnection();
if (uc instanceof JarURLConnection) {
urls.add(((JarURLConnection) uc).getJarFileURL());
}
}
}
Set classes = new HashSet();
for (URL url : urls) {
File file = new File(URLDecoder.decode(url.getFile(), "UTF-8"));
if (file.isDirectory()) {
Set files = getClassFiles(file.getAbsolutePath(),
new HashSet(),
file,
new int[]{200});
classes.addAll(files);
continue;
}
if (!file.isFile()) {
// TODO: handle directories
continue;
}
if (!file.toString().endsWith(".jar")) {
continue;
}
JarFile jf = new JarFile(file);
for (Enumeration e = jf.entries(); e.hasMoreElements();) {
JarEntry entry = e.nextElement();
if (entry == null) {
continue;
}
String name = entry.getName();
if (!name.endsWith(".class")) {
// only use class files
continue;
}
classes.add(name);
}
}
// now filter classes by changing "/" to "." and trimming the
// trailing ".class"
Set classNames = new TreeSet();
for (String name : classes) {
classNames.add(name.replace('/', '.').substring(0, name.length() - 6));
}
return classNames;
}
private static Set getClassFiles(
String root,
Set holder,
File directory,
int[] maxDirectories) {
// we have passed the maximum number of directories to scan
if (maxDirectories[0]-- < 0) {
return holder;
}
File[] files = directory.listFiles();
if (files == null) {
return holder;
}
for (File file : files) {
String name = file.getAbsolutePath();
if (!name.startsWith(root)) {
continue;
} else if (file.isDirectory()) {
getClassFiles(root, holder, file, maxDirectories);
} else if (file.getName().endsWith(".class")) {
holder.add(file.getAbsolutePath().substring(root.length() + 1));
}
}
return holder;
}
}
// End ClassNameCompleter.java
© 2015 - 2024 Weber Informatics LLC | Privacy Policy