001 /**
002 *
003 * Copyright 2004 Protique Ltd
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * 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 **/
018 package org.activemq.util;
019
020 import java.io.BufferedReader;
021 import java.io.IOException;
022 import java.io.InputStream;
023 import java.io.InputStreamReader;
024 import java.util.HashMap;
025 import java.util.Map;
026
027 /**
028 * A helper class to discover protocols dynamically to ensure
029 * that the system is extensible and has minimum runtime dependencies
030 *
031 * @version $Revision: 1.1.1.1 $
032 */
033 public class FactoryFinder {
034 private String path;
035 private Map classes = new HashMap();
036
037 public FactoryFinder(String path) {
038 this.path = path;
039 }
040
041 /**
042 * Creates a new instance of the given key
043 *
044 * @param key is the key to add to the path to find a text file containing the factory name
045 * @return a newly created instance
046 */
047 public Object newInstance(String key) throws IllegalAccessException, InstantiationException, IOException, ClassNotFoundException {
048 Class type = findClass(key);
049 return type.newInstance();
050 }
051
052 /**
053 * Loads the class for the given key
054 *
055 * @param key is the key to add to the path to find a text file containing the factory name
056 * @return the class for the given key
057 */
058 public Class findClass(String key) throws IOException, ClassNotFoundException {
059 Class answer = (Class) classes.get(key);
060 if (answer == null) {
061 answer = doFindClass(key);
062 classes.put(key, answer);
063 }
064 return answer;
065
066 }
067
068 private Class doFindClass(String key) throws IOException, ClassNotFoundException {
069 String uri = path + key;
070
071 // lets try the thread context class loader first
072 InputStream in = Thread.currentThread().getContextClassLoader().getResourceAsStream(uri);
073 if (in == null) {
074 in = getClass().getClassLoader().getResourceAsStream(uri);
075 if (in == null) {
076 throw new IOException("Could not find class for resource: " + uri);
077 }
078 }
079
080 // lets load the file
081 BufferedReader reader = null;
082 try {
083 reader = new BufferedReader(new InputStreamReader(in));
084 String line = reader.readLine();
085 if (line == null) {
086 throw new IOException("Empty file found for: " + uri);
087 }
088 line = line.trim();
089 Class answer = loadClass(line);
090 if (answer == null) {
091 throw new ClassNotFoundException("Could not find class: " + line);
092 }
093 return answer;
094 }
095 finally {
096 try {
097 reader.close();
098 }
099 catch (Exception e) {
100 // ignore
101 }
102 }
103 }
104
105 protected Class loadClass(String name) throws ClassNotFoundException {
106 try {
107 return Thread.currentThread().getContextClassLoader().loadClass(name);
108 }
109 catch (ClassNotFoundException e) {
110 return getClass().getClassLoader().loadClass(name);
111 }
112 }
113 }