Source code: org/dinopolis/util/servicediscovery/RepositoryClassLoader.java
1 /***********************************************************************
2 * @(#)$RCSfile: RepositoryClassLoader.java,v $ $Revision: 1.3 $$Date: 2003/11/18 09:12:13 $
3 *
4 * Copyright (c) 2003 IICM, Graz University of Technology
5 * Inffeldgasse 16c, A-8010 Graz, Austria.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License (LGPL)
9 * as published by the Free Software Foundation; either version 2.1 of
10 * the License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this program; if not, write to the
19 * Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 ***********************************************************************/
22
23
24 package org.dinopolis.util.servicediscovery;
25
26 import java.io.File;
27 import java.net.MalformedURLException;
28 import java.net.URL;
29 import java.net.URLClassLoader;
30 import java.util.List;
31 import java.util.Vector;
32 import org.dinopolis.util.Debug;
33
34 //----------------------------------------------------------------------
35 /**
36 * ClassLoader that allows to add all jar files in one or more
37 * repositories (directories). Additionally, a specific directory or a
38 * jar file can be added. This behavior allows to search in
39 * directories for jars even if they are not in the classpath
40 * (e.g. for plugin functionality).
41 * <p>
42
43 * Usage: create an instance of this classloader, add the repositories
44 * and urls the classloader should look for and call the
45 * <code>loadClass</code> method:
46 * <pre>
47 * RepositoryClassLoader loader = new RepositoryClassLoader();
48 * loader.addRepository("/home/cdaller/plugins");
49 * SuperPlugin plugin = (SuperPlugin)loader.loadClass("org.dinopolis.plugin.SuperPlugin").newInstance();
50 * </pre>
51 *
52 */
53 public class RepositoryClassLoader extends URLClassLoader
54 {
55 /*** Simple empty URL[0] array. */
56 public static final URL[] EMPTY_URL_ARRAY = new URL[0];
57
58 protected Vector repositories_ = new Vector();
59
60 //----------------------------------------------------------------------
61 /**
62 * Empty Constructor
63 */
64 public RepositoryClassLoader()
65 {
66 super(EMPTY_URL_ARRAY);
67 }
68
69 //----------------------------------------------------------------------
70 /**
71 * Constructor given a parent.
72 *
73 * @param parent The parent loader.
74 */
75 public RepositoryClassLoader(ClassLoader parent)
76 {
77 super(EMPTY_URL_ARRAY, parent);
78 }
79
80 //----------------------------------------------------------------------
81 /**
82 * Append a URL to this loader's search path.
83 *
84 * @param url The URL to append.
85 */
86 public void addURL(URL url)
87 {
88 super.addURL(url);
89 }
90
91 //----------------------------------------------------------------------
92 /**
93 * Produce output suitable for debugging.
94 *
95 * @return Output suitable for debugging.
96 */
97 public String toString()
98 {
99 return "[RepositoryClassLoader]";
100 }
101
102 // //----------------------------------------------------------------------
103 // /**
104 // * Find the resource with the given name, and return a String.
105 // * The search order is as described for <code>getResource()</code>,
106 // * after checking to see if the resource data has been previously cached.
107 // * If the resource cannot be found, return <code>null</code>.
108 // *
109 // * @param name Name of the resource to return a String for.
110 // */
111 // public String getResourceAsString( String name )
112 // {
113 // StringWriter sw = null;
114 // BufferedReader reader = null;
115
116 // try
117 // {
118 // sw = new StringWriter();
119 // InputStream is = getResourceAsStream( name );
120 // reader = new BufferedReader( new InputStreamReader( is ) );
121
122 // char buf[] = new char[1024];
123 // int len = 0;
124
125 // while ((len = reader.read(buf, 0, 1024)) != -1)
126 // {
127 // sw.write( buf, 0, len );
128 // }
129
130 // return sw.toString();
131 // }
132 // catch (IOException ioe)
133 // {
134 // return null;
135 // }
136 // finally
137 // {
138 // try
139 // {
140 // sw.close();
141 // reader.close();
142 // }
143 // catch (Exception ignored)
144 // {
145 // }
146 // }
147 // }
148
149 //----------------------------------------------------------------------
150 /**
151 * Add a new repository to the set of places this ClassLoader can look for
152 * classes to be loaded.
153 *
154 * @param repository Name of a source of classes to be loaded, such as a
155 * directory pathname, a JAR file pathname, or a ZIP file pathname. The
156 * parameter must be in the form of an URL.
157 * @exception IllegalArgumentException if the specified repository is
158 * invalid or does not exist
159 */
160 public void addRepository(String repository)
161 {
162 addRepository(new File(repository));
163 }
164
165 //----------------------------------------------------------------------
166 /**
167 * Add a new repository to the set of places this ClassLoader can look
168 * for classes to be loaded. The directory is parsed for ".jar" files
169 * and these jar files are added to the search path. This means that
170 * jars added to the directory after this method was called, are not
171 * used!
172 *
173 * @param repository Name of a source of classes to be loaded, such as a
174 * directory pathname, a JAR file pathname, or a ZIP file pathname. The
175 * parameter must be in the form of an URL.
176 * @exception IllegalArgumentException if the specified repository is
177 * invalid.
178 */
179 public void addRepository(File repository)
180 {
181 try
182 {
183 if (repository.exists())
184 {
185 if(repository.isDirectory())
186 {
187 if(Debug.DEBUG)
188 Debug.println("RepositoryClassLoader","adding Repository Directory: " + repository.toString());
189 repositories_.add(repository.toString());
190 File[] jars = repository.listFiles();
191
192 for (int j = 0; j < jars.length; j++)
193 {
194 if (jars[j].getAbsolutePath().endsWith(".jar"))
195 {
196 URL url = jars[j].toURL();
197 if(Debug.DEBUG)
198 Debug.println("RepositoryClassLoader","adding jar file " + url.toString());
199 super.addURL(url);
200 }
201 }
202 }
203 else
204 {
205 if(Debug.DEBUG)
206 Debug.println("RepositoryClassLoader","adding file " + repository);
207 super.addURL(repository.toURL());
208 }
209 }
210 }
211 catch (MalformedURLException e)
212 {
213 throw new IllegalArgumentException(e.toString());
214 }
215 }
216
217 //----------------------------------------------------------------------
218 /**
219 * Returns the repository names (in a list of Strings).
220 *
221 * @return a list of strings that indicate the repositories that were
222 * added to search for classes/resources.
223 */
224
225 public List getRepositories()
226 {
227 return(repositories_);
228 }
229 }