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 }