View Javadoc

1   package rydeen;
2   
3   import java.io.File;
4   import java.net.MalformedURLException;
5   import java.net.URL;
6   import java.net.URLClassLoader;
7   import java.security.AccessController;
8   import java.security.PrivilegedAction;
9   import java.util.ArrayList;
10  import java.util.List;
11  
12  /**
13   * <p>
14   * デフォルトの{@link ClassLoaderBuilder}です.
15   * 以下の場所を検索するクラスローダを構築します.
16   * </p>
17   * <ul>
18   *   <li>このクラスのロード元のjarファイルと同じ階層にある全てのjarファイルとzipファイル.</li>
19   *   <li>$HOME/.rydeen/lib 以下にある全てのjarファイルとzipファイル.</li>
20   *   <li>システムプロパティ rydeen.lib に設定されているjarファイルとzipファイル,もしくはディレクトリ.</li>
21   * </ul>
22   * <p>
23   * rydeen.lib はシステムのパス区切り文字(Windowsでは「;」,UNIXでは「:」で表される文字)
24   * で複数のディレクトリを指定できます.
25   * </p>
26   *
27   * @author Haruaki Tamada
28   */
29  public class LocalClassLoaderBuilder implements ClassLoaderBuilder{
30      public String getName(){
31          return "local";
32      }
33  
34      public ClassLoader createLoader() throws MalformedURLException{
35          final URL[] urls = collectUrls();
36          return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>(){
37              public ClassLoader run(){
38                  return new URLClassLoader(urls);
39              }
40          });
41      }
42  
43      URL[] collectUrls() throws MalformedURLException{
44          final List<URL> list = new ArrayList<URL>();
45          list.add(getJarUrlInThisClass());
46          for(URL url: getHomeLibUrls()){
47              if(url != null){
48                  list.add(url);
49              }
50          }
51          for(URL url: getSystemProperties()){
52              if(url != null){
53                  list.add(url);
54              }
55          }
56          return list.toArray(new URL[list.size()]);
57      }
58  
59      private void findJarsInDirectory(File dir, List<URL> list) throws MalformedURLException{
60          if(dir.isDirectory()){
61              for(File file: dir.listFiles()){
62                  String name = file.getName();
63                  if(file.isDirectory()){
64                      findJarsInDirectory(file, list);
65                  }
66                  else if(name.endsWith(".jar")){
67                      list.add(file.toURI().toURL());
68                  }
69              }
70          }
71      }
72  
73      private URL[] getHomeLibUrls() throws MalformedURLException{
74          File homeLibPath = new File(System.getProperty("user.home") + "/.rydeen/lib");
75          
76          List<URL> list = new ArrayList<URL>();
77          if(homeLibPath.exists() && homeLibPath.isDirectory()){
78              findJarsInDirectory(homeLibPath, list);
79          }
80          return list.toArray(new URL[list.size()]);
81      }
82  
83      private URL getJarUrlInThisClass() throws MalformedURLException{
84          URL url = getClass().getResource("/rydeen/LocalClassLoaderBuilder.class");
85          String path = url.toString();
86          if(path.startsWith("jar:")){
87              path = path.substring("jar:".length(), path.indexOf('!'));
88          }
89          if(path.startsWith("file:")){
90              if(path.endsWith(".class")){
91                  path = path.substring(0, path.indexOf("rydeen/LocalClassLoaderBuilder.class"));
92              }
93              url = new URL(path);
94          }
95          return url;
96      }
97  
98      private URL[] getSystemProperties() throws MalformedURLException{
99          String envPathList = System.getProperty("rydeen.lib");
100         String[] envPathArray = new String[0];
101         if(envPathList != null){
102             envPathArray = envPathList.split(File.pathSeparator);
103         }
104         URL[] urls = new URL[envPathArray.length];
105         for(int i = 0; i < envPathArray.length; i++){
106             File file = new File(envPathArray[i]);
107             if(file.exists()){
108                 urls[i] = file.toURI().toURL();
109             }
110             else{
111                 urls[i] = null;
112             }
113         }
114         return urls;
115 
116     }
117 }