001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache license, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the license for the specific language governing permissions and
015 * limitations under the license.
016 */
017package org.apache.logging.log4j.core.selector;
018
019import java.net.URI;
020import java.util.List;
021import java.util.Map;
022import java.util.concurrent.TimeUnit;
023
024import org.apache.logging.log4j.core.LoggerContext;
025
026/**
027 * Interface used to locate a LoggerContext.
028 */
029public interface ContextSelector {
030
031    long DEFAULT_STOP_TIMEOUT = 50;
032
033    /**
034     * Shuts down the LoggerContext.
035     * @param fqcn The fully qualified class name of the caller.
036     * @param loader The ClassLoader to use or null.
037     * @param currentContext If true returns the current Context, if false returns the Context appropriate
038     * @param allContexts if true all LoggerContexts that can be located will be shutdown.
039     * @since 2.13.0
040     */
041    default void shutdown(final String fqcn, final ClassLoader loader, final boolean currentContext,
042                          final boolean allContexts) {
043        if (hasContext(fqcn, loader, currentContext)) {
044            getContext(fqcn, loader, currentContext).stop(DEFAULT_STOP_TIMEOUT, TimeUnit.MILLISECONDS);
045        }
046    }
047
048    /**
049     * Checks to see if a LoggerContext is installed. The default implementation returns false.
050     * @param fqcn The fully qualified class name of the caller.
051     * @param loader The ClassLoader to use or null.
052     * @param currentContext If true returns the current Context, if false returns the Context appropriate
053     * for the caller if a more appropriate Context can be determined.
054     * @return true if a LoggerContext has been installed, false otherwise.
055     * @since 2.13.0
056     */
057    default boolean hasContext(String fqcn, ClassLoader loader, boolean currentContext) {
058        return false;
059    }
060
061    /**
062     * Returns the LoggerContext.
063     * @param fqcn The fully qualified class name of the caller.
064     * @param loader ClassLoader to use or null.
065     * @param currentContext If true returns the current Context, if false returns the Context appropriate
066     * for the caller if a more appropriate Context can be determined.
067     * @return The LoggerContext.
068     */
069    LoggerContext getContext(String fqcn, ClassLoader loader, boolean currentContext);
070
071    /**
072     * Returns the LoggerContext.
073     * @param fqcn The fully qualified class name of the caller.
074     * @param loader ClassLoader to use or null.
075     * @param entry An entry for the external Context map.
076     * @param currentContext If true returns the current Context, if false returns the Context appropriate
077     * for the caller if a more appropriate Context can be determined.
078     * @return The LoggerContext.
079     */
080    default LoggerContext getContext(String fqcn, ClassLoader loader, Map.Entry<String, Object> entry, boolean currentContext) {
081        LoggerContext lc = getContext(fqcn, loader, currentContext);
082        if (lc != null) {
083            lc.putObject(entry.getKey(), entry.getValue());
084        }
085        return lc;
086    }
087
088    /**
089     * Returns the LoggerContext.
090     * @param fqcn The fully qualified class name of the caller.
091     * @param loader ClassLoader to use or null.
092     * @param currentContext If true returns the current Context, if false returns the Context appropriate
093     * for the caller if a more appropriate Context can be determined.
094     * @param configLocation The location of the configuration for the LoggerContext.
095     * @return The LoggerContext.
096     */
097    LoggerContext getContext(String fqcn, ClassLoader loader, boolean currentContext, URI configLocation);
098
099    /**
100     * Returns the LoggerContext.
101     * @param fqcn The fully qualified class name of the caller.
102     * @param loader ClassLoader to use or null.
103     * @param currentContext If true returns the current Context, if false returns the Context appropriate
104     * for the caller if a more appropriate Context can be determined.
105     * @param configLocation The location of the configuration for the LoggerContext.
106     * @return The LoggerContext.
107     */
108    default LoggerContext getContext(String fqcn, ClassLoader loader, Map.Entry<String, Object> entry,
109            boolean currentContext, URI configLocation) {
110        LoggerContext lc = getContext(fqcn, loader, currentContext, configLocation);
111        if (lc != null) {
112            lc.putObject(entry.getKey(), entry.getValue());
113        }
114        return lc;
115    }
116
117    /**
118     * Returns a List of all the available LoggerContexts.
119     * @return The List of LoggerContexts.
120     */
121    List<LoggerContext> getLoggerContexts();
122
123    /**
124     * Remove any references to the LoggerContext.
125     * @param context The context to remove.
126     */
127    void removeContext(LoggerContext context);
128
129    /**
130     * Determines whether or not this ContextSelector depends on the callers classloader.
131     * This method should be overridden by implementations, however a default method is provided which always
132     * returns {@code true} to preserve the old behavior.
133     *
134     * @return true if the class loader is required.
135     * @since 2.15.0
136     */
137    default boolean isClassLoaderDependent() {
138        return true;
139    }
140}