001/*
002 * Copyright (c) 2024 QOS.ch Sarl (Switzerland)
003 * All rights reserved.
004 *
005 * Permission is hereby granted, free  of charge, to any person obtaining
006 * a  copy  of this  software  and  associated  documentation files  (the
007 * "Software"), to  deal in  the Software without  restriction, including
008 * without limitation  the rights to  use, copy, modify,  merge, publish,
009 * distribute,  sublicense, and/or sell  copies of  the Software,  and to
010 * permit persons to whom the Software  is furnished to do so, subject to
011 * the following conditions:
012 *
013 * The  above  copyright  notice  and  this permission  notice  shall  be
014 * included in all copies or substantial portions of the Software.
015 *
016 * THE  SOFTWARE IS  PROVIDED  "AS  IS", WITHOUT  WARRANTY  OF ANY  KIND,
017 * EXPRESS OR  IMPLIED, INCLUDING  BUT NOT LIMITED  TO THE  WARRANTIES OF
018 * MERCHANTABILITY,    FITNESS    FOR    A   PARTICULAR    PURPOSE    AND
019 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
020 * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
021 * OF CONTRACT, TORT OR OTHERWISE,  ARISING FROM, OUT OF OR IN CONNECTION
022 * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
023 *
024 *
025 *
026 */
027
028package ch.qos.logback.tyler.base.util;
029
030import ch.qos.logback.core.Context;
031import ch.qos.logback.core.joran.spi.NoAutoStart;
032import ch.qos.logback.core.spi.ContextAware;
033import ch.qos.logback.core.spi.LifeCycle;
034import ch.qos.logback.core.util.Loader;
035
036import static ch.qos.logback.core.CoreConstants.DOT;
037import static ch.qos.logback.tyler.base.TylerConstants.NOT_FOUND;
038
039public class ClassUtil {
040
041
042    public static boolean classImplements(Class<?> aClass, Class<?> otherClass) {
043        return otherClass.isAssignableFrom(aClass);
044    }
045
046
047    static public boolean shouldBeStarted(Class<?> aClass) {
048        if(classImplements(aClass, LifeCycle.class)) {
049            return notMarkedWithNoAutoStart(aClass);
050        } else
051            return false;
052    }
053
054    static public boolean notMarkedWithNoAutoStart(Class<?> aClass) {
055        NoAutoStart a = aClass.getAnnotation(NoAutoStart.class);
056        return a == null;
057    }
058
059    static final String[] AUTHORIZED_PREFIXES = {"ch.qos.logback", "chapters.appenders", "chapters.layouts", "chapters.filters"};
060
061    static public boolean isAuthorized(String classStr) {
062        for(String s: AUTHORIZED_PREFIXES) {
063            if (classStr.startsWith(s)) {
064                return true;
065            }
066        }
067        return false;
068    }
069
070    public static Class<?> restrictecLoadClass(String classStr, Context context) throws ClassNotFoundException {
071        if(!isAuthorized(classStr)) {
072            throw new IllegalArgumentException("Class name "+classStr+ " not supported");
073        }
074
075        ClassLoader cl = Loader.getClassLoaderOfObject(context);
076        return cl.loadClass(classStr);
077    }
078
079    public static String extractPackageName(String fqcn) {
080        int lastDotIndex = fqcn.lastIndexOf(DOT);
081        if (lastDotIndex != NOT_FOUND) {
082            String packageName = fqcn.substring(0, lastDotIndex);
083            return packageName;
084        } else {
085            return null;
086        }
087    }
088
089    public static String extractSimpleClassName(String fqcn) {
090        int lastDotIndex = fqcn.lastIndexOf(DOT);
091        if (lastDotIndex == NOT_FOUND) {
092            return fqcn;
093        }
094
095        if (lastDotIndex+1 < fqcn.length()) {
096            String className = fqcn.substring(lastDotIndex + 1);
097            return className;
098        } else {
099            return null;
100        }
101    }
102}