クラス名検索

理由はさておき、package 名から配下の classNameを取得したくなった。
ネットワーク越しのJARに対応するものまでは書く余裕がかった。
import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public static String[] findClass(String packagename) 
throws IOException,URISyntaxException{
   List<String> list = new ArrayList<String>();
   if (packagename==null || packagename.length() < 0) 
      return list.toArray(new String[]{});
   String target = packagename.replaceAll("\\.","/");
   if (!target.endsWith("/")) target = target + "/";
   URL url = ClassLoader.getSystemClassLoader()
             .getResource(target);
   if (url.getProtocol().equals("jar")){
      String path = url.toString()
                    .replaceFirst("jar:file:","");
      path = path.substring(0,path.indexOf("!"));
      JarFile jarfile = new JarFile(new File(path));
      for(Enumeration<JarEntry> en=jarfile.entries()
          ;en.hasMoreElements();){
         JarEntry entry = en.nextElement();
         String s = entry.getName();
         if (s.startsWith(target) 
             && s.indexOf("$") < 0 
             && s.endsWith(".class")){
            list.add(entry.getName()
            .replaceAll("\\.class$","")
            .replaceAll("/","."));
         }
      }
   }else if(url.getProtocol().equals("file")){
      String pname = target.replaceAll("/",".");
      File f = new File(url.toURI());
      String[] fary = f.list(new FilenameFilterImpl("^\\w+.class$"));
      for(String fname : fary){
         list.add(pname+fname.replaceAll("\\.class$",""));
      }
   }
   return list.toArray(new String[]{});
}
------- FilenameFilterImpl は、、、
import java.io.File;
import java.io.FilenameFilter;
import java.util.regex.Pattern;

public class FilenameFilterImpl implements FilenameFilter{
   private Pattern pattern;
   /**
    * コンストラクタ.
    * @param pattern java.util.regex.Pattern#compileを生成するための文字列
    */

   public FilenameFilterImpl(String pattern){
      this.pattern = Pattern.compile(pattern);
   }
   /***
    * java.io.FilenameFilter#accept(java.io.File,java.lang.String)の実装
    * @param dir ディレクトリを指すFile
    * @param name ファイル名、java.util.regex.Pattern#matcherを実行するための文字列
    * @return true=ファイルリストに含める
    */

   public boolean accept(File dir,String name){
      File f = new File(dir.getPath()+File.separator+name);
      if (f.isDirectory()) return false;        // ディレクトリは除く
      return this.pattern.matcher(name).matches();
   }
}
====== サンプル ============================================
String[] ts = findClass("com.google.inject.binder");
for(String name : ts){
   System.out.println("name = ["+name+"]");
}
====== 結果 ===============================================
name = [com.google.inject.binder.AnnotatedBindingBuilder]
name = [com.google.inject.binder.AnnotatedConstantBindingBuilder]
name = [com.google.inject.binder.AnnotatedElementBuilder]
name = [com.google.inject.binder.ConstantBindingBuilder]
name = [com.google.inject.binder.LinkedBindingBuilder]
name = [com.google.inject.binder.ScopedBindingBuilder]