/** * Copyright (c) 2000-present Liferay, Inc. All rights reserved. * * This library is free software; you can redistribute it and/or modify it under * the terms of the GNU Lesser General Public License as published by the Free * Software Foundation; either version 2.1 of the License, or (at your option) * any later version. * * This library is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more * details. */ package com.liferay.portal.kernel.util; import com.liferay.portal.kernel.log.Log; import com.liferay.portal.kernel.log.LogFactoryUtil; import java.io.BufferedReader; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.Constructor; import java.net.URL; import java.util.ArrayList; import java.util.Enumeration; import java.util.List; /** * @author Brian Wing Shun Chan * @author Miguel Pastor * @author Raymond Augé */ public class ServiceLoader { public static <S> List<S> load(Class<S> clazz) throws Exception { return load(clazz, _serviceLoaderCondition); } public static <S> List<S> load( Class<S> clazz, ServiceLoaderCondition serviceLoaderCondition) throws Exception { Thread currentThread = Thread.currentThread(); ClassLoader classLoader = currentThread.getContextClassLoader(); return load(classLoader, clazz, serviceLoaderCondition); } public static <S> List<S> load(ClassLoader classLoader, Class<S> clazz) throws Exception { return load(classLoader, clazz, _serviceLoaderCondition); } public static <S> List<S> load( ClassLoader classLoader, Class<S> clazz, ServiceLoaderCondition serviceLoaderCondition) throws Exception { Enumeration<URL> enu = classLoader.getResources( "META-INF/services/" + clazz.getName()); List<S> services = new ArrayList<>(); while (enu.hasMoreElements()) { URL url = enu.nextElement(); if (!serviceLoaderCondition.isLoad(url)) { continue; } try { _load(services, classLoader, clazz, url); } catch (Exception e) { _log.error( "Unable to load " + clazz + " with " + classLoader, e); } } return services; } private static <S> void _load( List<S> services, ClassLoader classLoader, Class<S> clazz, URL url) throws Exception { try (InputStream inputStream = url.openStream()) { BufferedReader bufferedReader = new BufferedReader( new InputStreamReader(inputStream, StringPool.UTF8)); while (true) { String line = bufferedReader.readLine(); if (line == null) { break; } int comment = line.indexOf(CharPool.POUND); if (comment >= 0) { line = line.substring(0, comment); } String name = line.trim(); if (name.length() == 0) { continue; } Class<?> serviceClass = Class.forName(name, true, classLoader); Class<? extends S> serviceImplClass = serviceClass.asSubclass( clazz); Constructor<? extends S> constructor = serviceImplClass.getConstructor(); S service = constructor.newInstance(); services.add(service); } } } private static final Log _log = LogFactoryUtil.getLog(ServiceLoader.class); private static final ServiceLoaderCondition _serviceLoaderCondition = new DefaultServiceLoaderCondition(); }