001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.xbean.finder;
018
019 import java.io.BufferedInputStream;
020 import java.io.File;
021 import java.io.IOException;
022 import java.io.InputStream;
023 import java.net.JarURLConnection;
024 import java.net.MalformedURLException;
025 import java.net.URL;
026 import java.util.ArrayList;
027 import java.util.Enumeration;
028 import java.util.HashMap;
029 import java.util.List;
030 import java.util.Map;
031 import java.util.Properties;
032 import java.util.Iterator;
033 import java.util.jar.JarEntry;
034 import java.util.jar.JarFile;
035
036 public class ResourceFinder {
037
038 private final String path;
039 private final ClassLoader classLoader;
040
041 public ResourceFinder(String path) {
042 this(path, Thread.currentThread().getContextClassLoader());
043 }
044
045 public ResourceFinder(String path, ClassLoader classLoader) {
046 this.path = path;
047 this.classLoader = classLoader;
048 }
049
050
051 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
052 //
053 // Find String
054 //
055 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
056
057 public String findString(String key) throws IOException {
058 String uri = path + key;
059
060 URL resource = classLoader.getResource(uri);
061 if (resource == null) {
062 throw new IOException("Could not find command in : " + uri);
063 }
064
065 return readContents(resource);
066 }
067
068 public List<String> findAllStrings(String key) throws IOException {
069 String uri = path + key;
070
071 List<String> strings = new ArrayList<String>();
072
073 Enumeration<URL> resources = classLoader.getResources(uri);
074 while (resources.hasMoreElements()) {
075 URL url = resources.nextElement();
076 String string = readContents(url);
077 strings.add(string);
078 }
079 return strings;
080 }
081
082 public List<String> findAvailableStrings(String key) throws IOException {
083 String uri = path + key;
084
085 List<String> strings = new ArrayList<String>();
086
087 Enumeration<URL> resources = classLoader.getResources(uri);
088 while (resources.hasMoreElements()) {
089 try {
090 URL url = resources.nextElement();
091 String string = readContents(url);
092 strings.add(string);
093 } catch (Exception notAvailable) {
094 }
095 }
096 return strings;
097 }
098
099 public Map<String,String> mapAllStrings(String key) throws IOException {
100 Map<String,String> strings = new HashMap<String,String>();
101 Map<String, URL> resourcesMap = getResourcesMap(key);
102 for (Iterator iterator = resourcesMap.entrySet().iterator(); iterator.hasNext();) {
103 Map.Entry entry = (Map.Entry) iterator.next();
104 String name = (String) entry.getKey();
105 URL url = (URL) entry.getValue();
106 String value = readContents(url);
107 strings.put(name,value);
108 }
109 return strings;
110 }
111
112 public Map<String,String> mapAvailableStrings(String key) throws IOException {
113 Map<String,String> strings = new HashMap<String,String>();
114 Map<String, URL> resourcesMap = getResourcesMap(key);
115 for (Iterator iterator = resourcesMap.entrySet().iterator(); iterator.hasNext();) {
116 try {
117 Map.Entry entry = (Map.Entry) iterator.next();
118 String name = (String) entry.getKey();
119 URL url = (URL) entry.getValue();
120 String value = readContents(url);
121 strings.put(name,value);
122 } catch (Exception notAvailable) {
123 }
124 }
125 return strings;
126 }
127
128
129 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
130 //
131 // Find Class
132 //
133 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
134
135 public Class findClass(String key) throws IOException, ClassNotFoundException {
136 String className = findString(key);
137 Class clazz = classLoader.loadClass(className);
138 return clazz;
139 }
140
141 public List<Class> findAllClasses(String key) throws IOException, ClassNotFoundException {
142 List<Class> classes = new ArrayList<Class>();
143 List<String> strings = findAllStrings(key);
144 for (String className : strings) {
145 Class clazz = classLoader.loadClass(className);
146 classes.add(clazz);
147 }
148 return classes;
149 }
150
151 public List<Class> findAvailableClasses(String key) throws IOException {
152 List<Class> classes = new ArrayList<Class>();
153 List<String> strings = findAvailableStrings(key);
154 for (String className : strings) {
155 try {
156 Class clazz = classLoader.loadClass(className);
157 classes.add(clazz);
158 } catch (Exception notAvailable) {
159 }
160 }
161 return classes;
162 }
163
164 public Map<String, Class> mapAllClasses(String key) throws IOException, ClassNotFoundException {
165 Map<String, Class> classes = new HashMap<String, Class>();
166 Map<String, String> map = mapAllStrings(key);
167 for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {
168 Map.Entry entry = (Map.Entry) iterator.next();
169 String string = (String) entry.getKey();
170 String className = (String) entry.getValue();
171 Class clazz = classLoader.loadClass(className);
172 classes.put(string, clazz);
173 }
174 return classes;
175 }
176
177 public Map<String, Class> mapAvailableClasses(String key) throws IOException {
178 Map<String, Class> classes = new HashMap<String, Class>();
179 Map<String, String> map = mapAvailableStrings(key);
180 for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {
181 try {
182 Map.Entry entry = (Map.Entry) iterator.next();
183 String string = (String) entry.getKey();
184 String className = (String) entry.getValue();
185 Class clazz = classLoader.loadClass(className);
186 classes.put(string, clazz);
187 } catch (Exception notAvailable) {
188 }
189 }
190 return classes;
191 }
192
193 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
194 //
195 // Find Implementation
196 //
197 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
198
199 public Class findImplementation(Class interfase) throws IOException, ClassNotFoundException {
200 String className = findString(interfase.getName());
201 Class impl = classLoader.loadClass(className);
202 if (!interfase.isAssignableFrom(impl)) {
203 throw new ClassCastException("Class not of type: " + interfase.getName());
204 }
205 return impl;
206 }
207
208 public List<Class> findAllImplementations(Class interfase) throws IOException, ClassNotFoundException {
209 List<Class> implementations = new ArrayList<Class>();
210 List<String> strings = findAllStrings(interfase.getName());
211 for (String className : strings) {
212 Class impl = classLoader.loadClass(className);
213 if (!interfase.isAssignableFrom(impl)) {
214 throw new ClassCastException("Class not of type: " + interfase.getName());
215 }
216 implementations.add(impl);
217 }
218 return implementations;
219 }
220
221 public List<Class> findAvailableImplementations(Class interfase) throws IOException {
222 List<Class> implementations = new ArrayList<Class>();
223 List<String> strings = findAvailableStrings(interfase.getName());
224 for (String className : strings) {
225 try {
226 Class impl = classLoader.loadClass(className);
227 if (interfase.isAssignableFrom(impl)) {
228 implementations.add(impl);
229 }
230 } catch (Exception notAvailable) {
231 }
232 }
233 return implementations;
234 }
235
236 public Map<String, Class> mapAllImplementations(Class interfase) throws IOException, ClassNotFoundException {
237 Map<String, Class> implementations = new HashMap<String, Class>();
238 Map<String, String> map = mapAllStrings(interfase.getName());
239 for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {
240 Map.Entry entry = (Map.Entry) iterator.next();
241 String string = (String) entry.getKey();
242 String className = (String) entry.getValue();
243 Class impl = classLoader.loadClass(className);
244 if (!interfase.isAssignableFrom(impl)) {
245 throw new ClassCastException("Class not of type: " + interfase.getName());
246 }
247 implementations.put(string, impl);
248 }
249 return implementations;
250 }
251
252 public Map<String, Class> mapAvailableImplementations(Class interfase) throws IOException {
253 Map<String, Class> implementations = new HashMap<String, Class>();
254 Map<String, String> map = mapAvailableStrings(interfase.getName());
255 for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {
256 try {
257 Map.Entry entry = (Map.Entry) iterator.next();
258 String string = (String) entry.getKey();
259 String className = (String) entry.getValue();
260 Class impl = classLoader.loadClass(className);
261 if (interfase.isAssignableFrom(impl)) {
262 implementations.put(string, impl);
263 }
264 } catch (Exception notAvailable) {
265 }
266 }
267 return implementations;
268 }
269
270
271 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
272 //
273 // Find Properties
274 //
275 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
276
277 public Properties findProperties(String key) throws IOException {
278 String uri = path + key;
279
280 URL resource = classLoader.getResource(uri);
281 if (resource == null) {
282 throw new IOException("Could not find command in : " + uri);
283 }
284
285 return loadProperties(resource);
286 }
287
288 public List<Properties> findAllProperties(String key) throws IOException {
289 String uri = path + key;
290
291 List<Properties> properties = new ArrayList<Properties>();
292
293 Enumeration<URL> resources = classLoader.getResources(uri);
294 while (resources.hasMoreElements()) {
295 URL url = resources.nextElement();
296 Properties props = loadProperties(url);
297 properties.add(props);
298 }
299 return properties;
300 }
301
302 public List<Properties> findAvailableProperties(String key) throws IOException {
303 String uri = path + key;
304
305 List<Properties> properties = new ArrayList<Properties>();
306
307 Enumeration<URL> resources = classLoader.getResources(uri);
308 while (resources.hasMoreElements()) {
309 try {
310 URL url = resources.nextElement();
311 Properties props = loadProperties(url);
312 properties.add(props);
313 } catch (Exception notAvailable) {
314 }
315 }
316 return properties;
317 }
318
319 public Map<String, Properties> mapAllProperties(String key) throws IOException {
320 Map<String, Properties> propertiesMap = new HashMap<String, Properties>();
321 Map<String, URL> map = getResourcesMap(key);
322 for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {
323 Map.Entry entry = (Map.Entry) iterator.next();
324 String string = (String) entry.getKey();
325 URL url = (URL) entry.getValue();
326 Properties properties = loadProperties(url);
327 propertiesMap.put(string, properties);
328 }
329 return propertiesMap;
330 }
331
332 public Map<String, Properties> mapAvailableProperties(String key) throws IOException {
333 Map<String, Properties> propertiesMap = new HashMap<String, Properties>();
334 Map<String, URL> map = getResourcesMap(key);
335 for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {
336 try {
337 Map.Entry entry = (Map.Entry) iterator.next();
338 String string = (String) entry.getKey();
339 URL url = (URL) entry.getValue();
340 Properties properties = loadProperties(url);
341 propertiesMap.put(string, properties);
342 } catch (Exception notAvailable) {
343 }
344 }
345 return propertiesMap;
346 }
347
348 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
349 //
350 // Map Resources
351 //
352 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
353
354 public Map<String, URL> getResourcesMap(String key) throws IOException {
355 String basePath = path + key;
356
357 Map<String, URL> resources = new HashMap<String, URL>();
358 if (!basePath.endsWith("/")){
359 basePath += "/";
360 }
361 Enumeration<URL> urls = classLoader.getResources(basePath);
362
363 while (urls.hasMoreElements()) {
364 URL location = urls.nextElement();
365
366 try {
367 if (location.getProtocol().equals("jar")) {
368
369 readJarEntries(location, basePath, resources);
370
371 } else if (location.getProtocol().equals("file")) {
372
373 readDirectoryEntries(location, resources);
374
375 }
376 } catch (Exception e) {
377 }
378 }
379
380 return resources;
381 }
382
383 private static void readDirectoryEntries(URL location, Map<String, URL> resources) throws MalformedURLException {
384 File dir = new File(location.getPath());
385 if (dir.isDirectory()) {
386 File[] files = dir.listFiles();
387 for (File file : files) {
388 if (!file.isDirectory()){
389 String name = file.getName();
390 URL url = file.toURL();
391 resources.put(name, url);
392 }
393 }
394 }
395 }
396
397 private static void readJarEntries(URL location, String basePath, Map<String, URL> resources) throws IOException {
398 JarURLConnection conn = (JarURLConnection) location.openConnection();
399 JarFile jarfile = conn.getJarFile();
400
401 Enumeration<JarEntry> entries = jarfile.entries();
402 while (entries != null && entries.hasMoreElements()) {
403 JarEntry entry = entries.nextElement();
404 String name = entry.getName();
405
406 if (entry.isDirectory() || !name.startsWith(basePath) || name.length() == basePath.length()) {
407 continue;
408 }
409
410 name = name.substring(basePath.length());
411
412 if (name.contains("/")) {
413 continue;
414 }
415
416 URL resource = new URL(location, name);
417 resources.put(name, resource);
418 }
419 }
420
421 private Properties loadProperties(URL resource) throws IOException {
422 InputStream in = resource.openStream();
423
424 BufferedInputStream reader = null;
425 try {
426 reader = new BufferedInputStream(in);
427 Properties properties = new Properties();
428 properties.load(reader);
429
430 return properties;
431 } finally {
432 try {
433 in.close();
434 reader.close();
435 } catch (Exception e) {
436 }
437 }
438 }
439
440 private String readContents(URL resource) throws IOException {
441 InputStream in = resource.openStream();
442 BufferedInputStream reader = null;
443 StringBuffer sb = new StringBuffer();
444
445 try {
446 reader = new BufferedInputStream(in);
447
448 int b = reader.read();
449 while (b != -1) {
450 sb.append((char) b);
451 b = reader.read();
452 }
453
454 return sb.toString().trim();
455 } finally {
456 try {
457 in.close();
458 reader.close();
459 } catch (Exception e) {
460 }
461 }
462 }
463
464
465 public Enumeration doFindCommands() throws IOException {
466 return Thread.currentThread().getContextClassLoader().getResources(path);
467 }
468
469 }