001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2015, QOS.ch. All rights reserved.
004 *
005 * This program and the accompanying materials are dual-licensed under
006 * either the terms of the Eclipse Public License v1.0 as published by
007 * the Eclipse Foundation
008 *
009 *   or (per the licensee's choosing)
010 *
011 * under the terms of the GNU Lesser General Public License version 2.1
012 * as published by the Free Software Foundation.
013 */
014package ch.qos.logback.classic.util;
015
016import java.lang.module.ModuleDescriptor;
017import java.util.*;
018
019import ch.qos.logback.core.util.EnvUtil;
020
021/**
022 * @author Ceki Gülcü
023 */
024public class ClassicEnvUtil {
025
026    /*
027     * Used to replace the ClassLoader that the ServiceLoader uses for unit testing.
028     * We need this to mock the resources the ServiceLoader attempts to load from
029     * /META-INF/services thus keeping the projects src/test/resources clean (see
030     * src/test/resources/README.txt).
031     */
032    //static ClassLoader testServiceLoaderClassLoader = null;
033
034    static public boolean isGroovyAvailable() {
035        return EnvUtil.isClassAvailable(ClassicEnvUtil.class, "groovy.lang.Binding");
036    }
037//
038//    private static ClassLoader getServiceLoaderClassLoader() {
039//        return testServiceLoaderClassLoader == null ? Loader.getClassLoaderOfClass(ClassicEnvUtil.class)
040//                : testServiceLoaderClassLoader;
041//    }
042
043    public static <T> List<T> loadFromServiceLoader(Class<T> c, ClassLoader classLoader) {
044        ServiceLoader<T> loader = ServiceLoader.load(c, classLoader);
045        List<T> listOfT = new ArrayList<>();
046        Iterator<T> it = loader.iterator();
047        while(it.hasNext()) {
048            T t = it.next();
049            listOfT.add(t);
050        }
051        return listOfT;
052    }
053
054    /**
055     * <p>Returns the current version of logback-classic, or null if data is not
056     * available.
057     * </p>
058     *
059     * @since 1.5.15
060     * @return current version or null if missing version data
061     */
062    static public String getVersionOfLogbackClassic() {
063        String moduleVersion = getVersionOfLogbackClassicByModule();
064        if (moduleVersion != null)
065            return moduleVersion;
066
067        Package pkg = ClassicEnvUtil.class.getPackage();
068        if (pkg == null) {
069            return null;
070        }
071        return pkg.getImplementationVersion();
072    }
073
074    /**
075     * <p>Returns the current version of logback-classic via class.getModule() or null
076     * if data is not available.
077     * </p>
078     *
079     * @since 1.5.15
080     * @return current version or null if missing version data
081     */
082    static private String getVersionOfLogbackClassicByModule() {
083        Module module = ClassicEnvUtil.class.getModule();
084        if (module == null)
085            return null;
086
087        ModuleDescriptor md = module.getDescriptor();
088        if (md == null)
089            return null;
090        Optional<String> opt = md.rawVersion();
091        return opt.orElse(null);
092    }
093}