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     */
017    package org.apache.logging.log4j.core.impl;
018    
019    import org.apache.logging.log4j.core.LoggerContext;
020    import org.apache.logging.log4j.core.helpers.Constants;
021    import org.apache.logging.log4j.core.helpers.Loader;
022    import org.apache.logging.log4j.core.selector.ClassLoaderContextSelector;
023    import org.apache.logging.log4j.core.selector.ContextSelector;
024    import org.apache.logging.log4j.status.StatusLogger;
025    import org.apache.logging.log4j.spi.LoggerContextFactory;
026    import org.apache.logging.log4j.util.PropertiesUtil;
027    
028    /**
029     * Factory to locate a ContextSelector and then load a LoggerContext.
030     */
031    public class Log4jContextFactory implements LoggerContextFactory {
032    
033        private static final StatusLogger LOGGER = StatusLogger.getLogger();
034    
035        private ContextSelector selector;
036    
037        /**
038         * Constructor that initializes the ContextSelector.
039         */
040        public Log4jContextFactory() {
041            final String sel = PropertiesUtil.getProperties().getStringProperty(Constants.LOG4J_CONTEXT_SELECTOR);
042            if (sel != null) {
043                try {
044                    final Class clazz = Loader.loadClass(sel);
045                    if (clazz != null && ContextSelector.class.isAssignableFrom(clazz)) {
046                        selector = (ContextSelector) clazz.newInstance();
047                        return;
048                    }
049                } catch (final Exception ex) {
050                    LOGGER.error("Unable to create context " + sel, ex);
051                }
052    
053            }
054            selector = new ClassLoaderContextSelector();
055        }
056    
057        /**
058         * Returns the ContextSelector.
059         * @return The ContextSelector.
060         */
061        public ContextSelector getSelector() {
062            return selector;
063        }
064    
065        /**
066         * Load the LoggerContext using the ContextSelector.
067         * @param fqcn The fully qualified class name of the caller.
068         * @param loader The ClassLoader to use or null.
069         * @param currentContext If true returns the current Context, if false returns the Context appropriate
070         * for the caller if a more appropriate Context can be determined.
071         * @return The LoggerContext.
072         */
073        public LoggerContext getContext(final String fqcn, final ClassLoader loader, final boolean currentContext) {
074            final LoggerContext ctx = selector.getContext(fqcn, loader, currentContext);
075            if (ctx.getStatus() == LoggerContext.Status.INITIALIZED) {
076                ctx.start();
077            }
078            return ctx;
079        }
080    }