All Downloads are FREE. Search and download functionalities are using the official Maven repository.

sqlline.ClassNameCompleter Maven / Gradle / Ivy

There is a newer version: 4.15.0-HBase-1.5
Show newest version
/*
// 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