001/* 002 * HA-JDBC: High-Availability JDBC 003 * Copyright (C) 2012 Paul Ferraro 004 * 005 * This program is free software: you can redistribute it and/or modify 006 * it under the terms of the GNU Lesser General Public License as published by 007 * the Free Software Foundation, either version 3 of the License, or 008 * (at your option) any later version. 009 * 010 * This program is distributed in the hope that it will be useful, 011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 013 * GNU Lesser General Public License for more details. 014 * 015 * You should have received a copy of the GNU Lesser General Public License 016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 017 */ 018package net.sf.hajdbc.util; 019 020import java.util.Iterator; 021import java.util.LinkedList; 022import java.util.List; 023import java.util.ServiceConfigurationError; 024import java.util.ServiceLoader; 025 026import net.sf.hajdbc.logging.Level; 027import net.sf.hajdbc.logging.Logger; 028import net.sf.hajdbc.logging.LoggerFactory; 029 030public class ServiceLoaders 031{ 032 private static final Logger logger = LoggerFactory.getLogger(ServiceLoaders.class); 033 034 public static <T> T findService(Class<T> serviceClass) 035 { 036 Iterator<T> services = ServiceLoader.load(serviceClass, serviceClass.getClassLoader()).iterator(); 037 038 while (services.hasNext()) 039 { 040 try 041 { 042 return services.next(); 043 } 044 catch (ServiceConfigurationError e) 045 { 046 logger.log(Level.DEBUG, e.getLocalizedMessage()); 047 } 048 } 049 return null; 050 } 051 052 public static <T> T findRequiredService(Class<T> serviceClass) 053 { 054 T service = findService(serviceClass); 055 if (service == null) 056 { 057 throw new IllegalStateException(String.format("No %s found", serviceClass.getName())); 058 } 059 return service; 060 } 061 062 public static <T> T findService(Matcher<T> matcher, Class<T> serviceClass) 063 { 064 List<T> matches = new LinkedList<T>(); 065 Iterator<T> services = ServiceLoader.load(serviceClass, serviceClass.getClassLoader()).iterator(); 066 067 while (services.hasNext()) 068 { 069 try 070 { 071 T service = services.next(); 072 if (matcher.matches(service)) 073 { 074 matches.add(service); 075 } 076 } 077 catch (ServiceConfigurationError e) 078 { 079 logger.log(Level.DEBUG, e.getLocalizedMessage()); 080 } 081 } 082 083 if (matches.size() > 1) 084 { 085 logger.log(Level.WARN, "Multiple {0} found matching {1}: {2}", serviceClass.getName(), matcher, matches); 086 } 087 088 return !matches.isEmpty() ? matches.get(0) : null; 089 } 090 091 public static <T> T findRequiredService(Matcher<T> matcher, Class<T> serviceClass) 092 { 093 T service = findService(matcher, serviceClass); 094 if (service == null) 095 { 096 throw new IllegalArgumentException(String.format("No %s found matching %s", serviceClass.getName(), matcher)); 097 } 098 return service; 099 } 100 101 private ServiceLoaders() 102 { 103 // Hide 104 } 105}