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.commons.discovery.tools;
018:
019: import java.io.IOException;
020: import java.io.InputStream;
021: import java.util.Properties;
022:
023: import org.apache.commons.discovery.DiscoveryException;
024: import org.apache.commons.discovery.Resource;
025: import org.apache.commons.discovery.ResourceIterator;
026: import org.apache.commons.discovery.resource.ClassLoaders;
027: import org.apache.commons.discovery.resource.DiscoverResources;
028:
029: /**
030: * Mechanisms to locate and load a class.
031: * The load methods locate a class only.
032: * The find methods locate a class and verify that the
033: * class implements an given interface or extends a given class.
034: *
035: * @author Richard A. Sitze
036: * @author Craig R. McClanahan
037: * @author Costin Manolache
038: */
039: public class ResourceUtils {
040: /**
041: * Get package name.
042: * Not all class loaders 'keep' package information,
043: * in which case Class.getPackage() returns null.
044: * This means that calling Class.getPackage().getName()
045: * is unreliable at best.
046: */
047: public static String getPackageName(Class clazz) {
048: Package clazzPackage = clazz.getPackage();
049: String packageName;
050: if (clazzPackage != null) {
051: packageName = clazzPackage.getName();
052: } else {
053: String clazzName = clazz.getName();
054: packageName = new String(clazzName.toCharArray(), 0,
055: clazzName.lastIndexOf('.'));
056: }
057: return packageName;
058: }
059:
060: /**
061: * Load the resource <code>resourceName</code>.
062: * Try each classloader in succession,
063: * until first succeeds, or all fail.
064: * If all fail and <code>resouceName</code> is not absolute
065: * (doesn't start with '/' character), then retry with
066: * <code>packageName/resourceName</code> after changing all
067: * '.' to '/'.
068: *
069: * @param resourceName The name of the resource to load.
070: */
071: public static Resource getResource(Class spi, String resourceName,
072: ClassLoaders loaders) throws DiscoveryException {
073: DiscoverResources explorer = new DiscoverResources(loaders);
074: ResourceIterator resources = explorer
075: .findResources(resourceName);
076:
077: if (spi != null && !resources.hasNext()
078: && resourceName.charAt(0) != '/') {
079: /**
080: * If we didn't find the resource, and if the resourceName
081: * isn't an 'absolute' path name, then qualify with
082: * package name of the spi.
083: */
084: resourceName = getPackageName(spi).replace('.', '/') + "/"
085: + resourceName;
086: resources = explorer.findResources(resourceName);
087: }
088:
089: return resources.hasNext() ? resources.nextResource() : null;
090: }
091:
092: /**
093: * Load named property file, optionally qualifed by spi's package name
094: * as per Class.getResource.
095: *
096: * A property file is loaded using the following sequence of class loaders:
097: * <ul>
098: * <li>Thread Context Class Loader</li>
099: * <li>DiscoverSingleton's Caller's Class Loader</li>
100: * <li>SPI's Class Loader</li>
101: * <li>DiscoverSingleton's (this class) Class Loader</li>
102: * <li>System Class Loader</li>
103: * </ul>
104: *
105: * @param propertiesFileName The property file name.
106: *
107: * @return Instance of a class implementing the SPI.
108: *
109: * @exception DiscoveryException Thrown if the name of a class implementing
110: * the SPI cannot be found, if the class cannot be loaded and
111: * instantiated, or if the resulting class does not implement
112: * (or extend) the SPI.
113: */
114: public static Properties loadProperties(Class spi,
115: String propertiesFileName, ClassLoaders classLoaders)
116: throws DiscoveryException {
117: Properties properties = null;
118:
119: if (propertiesFileName != null) {
120: try {
121: Resource resource = getResource(spi,
122: propertiesFileName, classLoaders);
123: if (resource != null) {
124: InputStream stream = resource.getResourceAsStream();
125:
126: if (stream != null) {
127: properties = new Properties();
128: try {
129: properties.load(stream);
130: } finally {
131: stream.close();
132: }
133: }
134: }
135: } catch (IOException e) {
136: // ignore
137: } catch (SecurityException e) {
138: // ignore
139: }
140: }
141:
142: return properties;
143: }
144: }
|