b1a398a69d38315c69458a0725aa17c9bac1bda9
[guacamole.git] / src / main / java / net / sourceforge / guacamole / net / basic / GuacamoleClassLoader.java
1
2 package net.sourceforge.guacamole.net.basic;
3
4 import java.io.File;
5 import java.io.FilenameFilter;
6 import java.net.MalformedURLException;
7 import java.net.URL;
8 import java.net.URLClassLoader;
9 import java.util.ArrayList;
10 import java.util.Collection;
11 import net.sourceforge.guacamole.GuacamoleException;
12 import net.sourceforge.guacamole.net.basic.properties.BasicGuacamoleProperties;
13 import net.sourceforge.guacamole.properties.GuacamoleProperties;
14
15 /*
16  *  Guacamole - Clientless Remote Desktop
17  *  Copyright (C) 2010  Michael Jumper
18  *
19  *  This program is free software: you can redistribute it and/or modify
20  *  it under the terms of the GNU Affero General Public License as published by
21  *  the Free Software Foundation, either version 3 of the License, or
22  *  (at your option) any later version.
23  *
24  *  This program is distributed in the hope that it will be useful,
25  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
26  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
27  *  GNU Affero General Public License for more details.
28  *
29  *  You should have received a copy of the GNU Affero General Public License
30  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
31  */
32
33 public class GuacamoleClassLoader extends ClassLoader {
34     
35     private URLClassLoader classLoader = null;
36
37     private static GuacamoleException exception = null;
38     private static GuacamoleClassLoader instance = null;
39     
40     static {
41         
42         try {
43             // Attempt to create singleton classloader which loads classes from
44             // all .jar's in the lib directory defined in guacamole.properties
45             instance = new GuacamoleClassLoader(
46                 GuacamoleProperties.getProperty(BasicGuacamoleProperties.LIB_DIRECTORY)
47             );
48         }
49         
50         catch (GuacamoleException e) {
51             // On error, record exception
52             exception = e;
53         }
54         
55     }
56
57     private GuacamoleClassLoader(File libDirectory) throws GuacamoleException {
58
59         // If no directory provided, just direct requests to parent classloader
60         if (libDirectory == null)
61             return;
62         
63         // Validate directory is indeed a directory
64         if (!libDirectory.isDirectory())
65             throw new GuacamoleException(libDirectory + " is not a directory.");
66         
67         // Get list of URLs for all .jar's in the lib directory
68         Collection<URL> jarURLs = new ArrayList<URL>();
69         for (File file : libDirectory.listFiles(new FilenameFilter() {
70
71             @Override
72             public boolean accept(File dir, String name) {
73                 
74                 // If it ends with .jar, accept the file
75                 return name.endsWith(".jar");
76                 
77             }
78
79         })) {
80
81             try {
82                 
83                 // Add URL for the .jar to the jar URL list
84                 jarURLs.add(file.toURI().toURL());
85                 
86             }
87             catch (MalformedURLException e) {
88                 throw new GuacamoleException(e);
89             }
90                 
91         }
92         
93         // Set delegate classloader to new URLClassLoader which loads from the
94         // .jars found above.
95
96         URL[] urls = new URL[jarURLs.size()];
97         classLoader = new URLClassLoader(
98             jarURLs.toArray(urls),
99             getClass().getClassLoader()
100         );
101         
102     }
103
104     public static GuacamoleClassLoader getInstance() throws GuacamoleException {
105         
106         // If instance could not be created, rethrow original exception
107         if (exception != null) throw exception;
108         
109         return instance;
110
111     }
112
113     @Override
114     protected Class<?> findClass(String name) throws ClassNotFoundException {
115
116         // If no classloader, use super
117         if (classLoader == null)
118             return super.findClass(name);
119         
120         // Otherwise, delegate
121         return classLoader.loadClass(name);
122
123     }
124
125 }