All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.github.azbh111.utils.java.spi.SPIUtils Maven / Gradle / Ivy

The newest version!
package com.github.azbh111.utils.java.spi;


import com.github.azbh111.utils.java.predicate.PredicateUtils;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;

/**
 *
 * @author pyz
 * @date 2019/3/30 2:28 PM
 */
public class SPIUtils {

    private static final String PREFIX = "META-INF/services/";

    public static  ServiceLoader load(Class service) {
        return ServiceLoader.load(service, Thread.currentThread().getContextClassLoader());
    }

    public static  ServiceLoader load(Class service, ClassLoader classLoader) {
        return ServiceLoader.load(service, classLoader);
    }

    public static  ServiceLoader loadInstalled(Class service) {
        return ServiceLoader.loadInstalled(service);
    }

    /**
     * 获取service的实现类
     *
     * @param service
     * @param 
     * @return
     */
    public static  List> loadClass(Class service) {
        return loadClass(service, Thread.currentThread().getContextClassLoader());
    }

    /**
     * 获取service的实现类
     *
     * @param service
     * @param 
     * @return
     */
    public static  List> loadClass(Class service, ClassLoader classLoader) {
        try {
            String fullName = PREFIX + service.getName();
            Enumeration configs = null;
            if (classLoader == null) {
                configs = ClassLoader.getSystemResources(fullName);
            } else {
                configs = classLoader.getResources(fullName);
            }

            if (configs == null) {
                return new ArrayList<>();
            }
            Predicate test = PredicateUtils.distinctBy(Function.identity());
            List services = new ArrayList<>();
            while (configs.hasMoreElements()) {
                URL url = configs.nextElement();
                for (String s : parse(service, url)) {
                    if (test.test(s)) {
                        services.add(s);
                    }
                }
            }
            List> classes = new ArrayList<>(services.size());
            Class c = null;
            for (String s : services) {
                try {
                    c = Class.forName(s, true, classLoader);
                } catch (ClassNotFoundException x) {
                    fail(service,
                            "Provider " + s + " not found");
                }
                if (!service.isAssignableFrom(c)) {
                    fail(service,
                            "Provider " + s + " not a subtype");
                }
                classes.add(c);
            }
            return classes;
        } catch (IOException x) {
            throw new ServiceConfigurationError(service.getName() + ": Error locating configuration files", x);
        }
    }


    private static List parse(Class service, URL u)
            throws ServiceConfigurationError, IOException {
        List names = new ArrayList<>();
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(u.openStream(), StandardCharsets.UTF_8))) {
            int lc = 1;
            while ((lc = parseLine(service, u, reader, lc, names)) >= 0) {
                ;
            }
        }
        return names;
    }

    // Parse a single line from the given configuration file, adding the name
    // on the line to the names list.
    //
    private static int parseLine(Class service, URL u, BufferedReader r, int lc,
                                 List names)
            throws IOException, ServiceConfigurationError {
        String ln = r.readLine();
        if (ln == null) {
            return -1;
        }
        int ci = ln.indexOf('#');
        if (ci >= 0) {
            ln = ln.substring(0, ci);
        }
        ln = ln.trim();
        int n = ln.length();
        if (n != 0) {
            if ((ln.indexOf(' ') >= 0) || (ln.indexOf('\t') >= 0)) {
                fail(service, u, lc, "Illegal configuration-file syntax");
            }
            int cp = ln.codePointAt(0);
            if (!Character.isJavaIdentifierStart(cp)) {
                fail(service, u, lc, "Illegal provider-class name: " + ln);
            }
            for (int i = Character.charCount(cp); i < n; i += Character.charCount(cp)) {
                cp = ln.codePointAt(i);
                if (!Character.isJavaIdentifierPart(cp) && (cp != '.')) {
                    fail(service, u, lc, "Illegal provider-class name: " + ln);
                }
            }
            names.add(ln);
        }
        return lc + 1;
    }

    private static void fail(Class service, String msg, Throwable cause)
            throws ServiceConfigurationError {
        throw new ServiceConfigurationError(service.getName() + ": " + msg,
                cause);
    }

    private static void fail(Class service, String msg)
            throws ServiceConfigurationError {
        throw new ServiceConfigurationError(service.getName() + ": " + msg);
    }

    private static void fail(Class service, URL u, int line, String msg)
            throws ServiceConfigurationError {
        fail(service, u + ":" + line + ": " + msg);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy