001 /** 002 * 003 * Licensed to the Apache Software Foundation (ASF) under one or more 004 * contributor license agreements. See the NOTICE file distributed with 005 * this work for additional information regarding copyright ownership. 006 * The ASF licenses this file to You under the Apache License, Version 2.0 007 * (the "License"); you may not use this file except in compliance with 008 * the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 package org.apache.camel.util; 019 020 import org.apache.camel.spi.Injector; 021 022 import java.io.BufferedInputStream; 023 import java.io.IOException; 024 import java.io.InputStream; 025 import java.util.Properties; 026 import java.util.concurrent.ConcurrentHashMap; 027 028 public class FactoryFinder { 029 private final String path; 030 private final ConcurrentHashMap classMap = new ConcurrentHashMap(); 031 032 public FactoryFinder() { 033 this("META-INF/services/org/apache/camel/"); 034 } 035 036 public FactoryFinder(String path) { 037 this.path = path; 038 } 039 040 /** 041 * Creates a new instance of the given key 042 * 043 * @param key is the key to add to the path to find a text file 044 * containing the factory name 045 * @return a newly created instance 046 */ 047 public Object newInstance(String key) 048 throws IllegalAccessException, InstantiationException, IOException, ClassNotFoundException { 049 return newInstance(key, (String) null); 050 } 051 052 public Object newInstance(String key, String propertyPrefix) 053 throws IllegalAccessException, InstantiationException, IOException, ClassNotFoundException { 054 Class clazz = findClass(key, propertyPrefix); 055 return clazz.newInstance(); 056 } 057 058 public Object newInstance(String key, Injector injector) throws IOException, ClassNotFoundException { 059 return newInstance(key, injector, null); 060 } 061 062 public Object newInstance(String key, Injector injector, String propertyPrefix) throws IOException, ClassNotFoundException { 063 Class type = findClass(key, propertyPrefix); 064 return injector.newInstance(type); 065 } 066 067 public Class findClass(String key) throws ClassNotFoundException, IOException { 068 return findClass(key, null); 069 } 070 071 public Class findClass(String key, String propertyPrefix) throws ClassNotFoundException, IOException { 072 if (propertyPrefix == null) { 073 propertyPrefix = ""; 074 } 075 076 Class clazz = (Class) classMap.get(propertyPrefix + key); 077 if (clazz == null) { 078 clazz = newInstance(doFindFactoryProperies(key), propertyPrefix); 079 classMap.put(propertyPrefix + key, clazz); 080 } 081 return clazz; 082 } 083 084 private Class newInstance(Properties properties, String propertyPrefix) throws ClassNotFoundException, IOException { 085 086 String className = properties.getProperty(propertyPrefix + "class"); 087 if (className == null) { 088 throw new IOException("Expected property is missing: " + propertyPrefix + "class"); 089 } 090 Class clazz = null; 091 ClassLoader loader = Thread.currentThread().getContextClassLoader(); 092 if (loader != null) { 093 try { 094 clazz = loader.loadClass(className); 095 } 096 catch (ClassNotFoundException e) { 097 // ignore 098 } 099 } 100 if (clazz == null) { 101 clazz = FactoryFinder.class.getClassLoader().loadClass(className); 102 } 103 return clazz; 104 } 105 106 private Properties doFindFactoryProperies(String key) throws IOException { 107 String uri = path + key; 108 109 // lets try the thread context class loader first 110 ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); 111 if (classLoader == null) { 112 classLoader = getClass().getClassLoader(); 113 } 114 InputStream in = classLoader.getResourceAsStream(uri); 115 if (in == null) { 116 in = FactoryFinder.class.getClassLoader().getResourceAsStream(uri); 117 if (in == null) { 118 throw new NoFactoryAvailableException(uri); 119 } 120 } 121 122 // lets load the file 123 BufferedInputStream reader = null; 124 try { 125 reader = new BufferedInputStream(in); 126 Properties properties = new Properties(); 127 properties.load(reader); 128 return properties; 129 } 130 finally { 131 try { 132 reader.close(); 133 } 134 catch (Exception e) { 135 } 136 } 137 } 138 }