1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.discovery.tools;
18
19 import java.io.IOException;
20 import java.io.InputStream;
21 import java.util.Properties;
22
23 import org.apache.commons.discovery.DiscoveryException;
24 import org.apache.commons.discovery.Resource;
25 import org.apache.commons.discovery.ResourceIterator;
26 import org.apache.commons.discovery.resource.ClassLoaders;
27 import org.apache.commons.discovery.resource.DiscoverResources;
28
29
30 /***
31 * Mechanisms to locate and load a class.
32 * The load methods locate a class only.
33 * The find methods locate a class and verify that the
34 * class implements an given interface or extends a given class.
35 *
36 * @author Richard A. Sitze
37 * @author Craig R. McClanahan
38 * @author Costin Manolache
39 */
40 public class ResourceUtils {
41 /***
42 * Get package name.
43 * Not all class loaders 'keep' package information,
44 * in which case Class.getPackage() returns null.
45 * This means that calling Class.getPackage().getName()
46 * is unreliable at best.
47 */
48 public static String getPackageName(Class clazz) {
49 Package clazzPackage = clazz.getPackage();
50 String packageName;
51 if (clazzPackage != null) {
52 packageName = clazzPackage.getName();
53 } else {
54 String clazzName = clazz.getName();
55 packageName = new String(clazzName.toCharArray(), 0, clazzName.lastIndexOf('.'));
56 }
57 return</strong> packageName;
58 }
59
60
61 /***
62 * Load the resource <code>resourceName</code>.
63 * Try each classloader in succession,
64 * until first succeeds, or all fail.
65 * If all fail and <code>resouceName</code> is not absolute
66 * (doesn't start with '/' character), then retry with
67 * <code>packageName/resourceName</code> after changing all
68 * '.' to '/'.
69 *
70 * @param resourceName The name of the resource to load.
71 */
72 public static Resource getResource(Class spi,
73 String resourceName,
74 ClassLoaders loaders)
75 throws DiscoveryException
76 {
77 DiscoverResources explorer = new DiscoverResources(loaders);
78 ResourceIterator resources = explorer.findResources(resourceName);
79
80 if (spi != null &&
81 !resources.hasNext() &&
82 resourceName.charAt(0) != '/')
83 {
84 /***
85 * If we didn't find the resource, and if the resourceName
86 * isn't an 'absolute' path name, then qualify with
87 * package name of the spi.
88 */
89 resourceName = getPackageName(spi).replace('.','/') + "/" + resourceName;
90 resources = explorer.findResources(resourceName);
91 }
92
93 return resources.hasNext()
94 ? resources.nextResource()
95 : null;
96 }
97
98 /***
99 * Load named property file, optionally qualifed by spi's package name
100 * as per Class.getResource.
101 *
102 * A property file is loaded using the following sequence of class loaders:
103 * <ul>
104 * <li>Thread Context Class Loader</li>
105 * <li>DiscoverSingleton's Caller's Class Loader</li>
106 * <li>SPI's Class Loader</li>
107 * <li>DiscoverSingleton's (this class) Class Loader</li>
108 * <li>System Class Loader</li>
109 * </ul>
110 *
111 * @param propertiesFileName The property file name.
112 *
113 * @return Instance of a class implementing the SPI.
114 *
115 * @exception DiscoveryException Thrown if the name of a class implementing
116 * the SPI cannot be found, if the class cannot be loaded and
117 * instantiated, or if the resulting class does not implement
118 * (or extend) the SPI.
119 */
120 public static Properties loadProperties(Class spi,
121 String propertiesFileName,
122 ClassLoaders classLoaders)
123 throws DiscoveryException
124 {
125 Properties properties = null;
126
127 if (propertiesFileName != null) {
128 try {
129 Resource resource = getResource(spi, propertiesFileName, classLoaders);
130 if (resource != null) {
131 InputStream stream = resource.getResourceAsStream();
132
133 if (stream != null) {
134 properties = new Properties();
135 try {
136 properties.load(stream);
137 } finally {
138 stream.close();
139 }
140 }
141 }
142 } catch (IOException e) {
143
144 } catch (SecurityException e) {
145
146 }
147 }
148
149 return properties;
150 }
151 }