JoranConfigurator.java
/**
* Logback: the reliable, generic, fast and flexible logging framework.
* Copyright (C) 1999-2015, QOS.ch. All rights reserved.
*
* This program and the accompanying materials are dual-licensed under
* either the terms of the Eclipse Public License v1.0 as published by
* the Eclipse Foundation
*
* or (per the licensee's choosing)
*
* under the terms of the GNU Lesser General Public License version 2.1
* as published by the Free Software Foundation.
*/
package ch.qos.logback.classic.joran;
import ch.qos.logback.classic.joran.action.ConfigurationAction;
import ch.qos.logback.classic.joran.action.ConsolePluginAction;
import ch.qos.logback.classic.joran.action.ContextNameAction;
import ch.qos.logback.classic.joran.action.InsertFromJNDIAction;
import ch.qos.logback.classic.joran.action.LevelAction;
import ch.qos.logback.classic.joran.action.LoggerAction;
import ch.qos.logback.classic.joran.action.LoggerContextListenerAction;
import ch.qos.logback.classic.joran.action.ReceiverAction;
import ch.qos.logback.classic.joran.action.RootLoggerAction;
import ch.qos.logback.classic.joran.sanity.IfNestedWithinSecondPhaseElementSC;
import ch.qos.logback.classic.model.ConfigurationModel;
import ch.qos.logback.classic.model.ContextNameModel;
import ch.qos.logback.classic.model.LevelModel;
import ch.qos.logback.classic.model.LoggerContextListenerModel;
import ch.qos.logback.classic.model.LoggerModel;
import ch.qos.logback.classic.model.RootLoggerModel;
import ch.qos.logback.classic.model.processor.ConfigurationModelHandler;
import ch.qos.logback.classic.model.processor.ContextNameModelHandler;
import ch.qos.logback.classic.model.processor.LevelModelHandler;
import ch.qos.logback.classic.model.processor.LogbackClassicDefaultNestedComponentRules;
import ch.qos.logback.classic.model.processor.LoggerContextListenerModelHandler;
import ch.qos.logback.classic.model.processor.LoggerModelHandler;
import ch.qos.logback.classic.model.processor.RootLoggerModelHandler;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.joran.JoranConfiguratorBase;
import ch.qos.logback.core.joran.action.AppenderRefAction;
import ch.qos.logback.core.joran.action.IncludeAction;
import ch.qos.logback.core.joran.sanity.AppenderWithinAppenderSanityChecker;
import ch.qos.logback.core.joran.sanity.SanityChecker;
import ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry;
import ch.qos.logback.core.joran.spi.ElementSelector;
import ch.qos.logback.core.joran.spi.RuleStore;
import ch.qos.logback.core.model.AppenderModel;
import ch.qos.logback.core.model.AppenderRefModel;
import ch.qos.logback.core.model.InsertFromJNDIModel;
import ch.qos.logback.core.model.Model;
import ch.qos.logback.core.model.processor.AppenderModelHandler;
import ch.qos.logback.core.model.processor.AppenderRefDependencyAnalyser;
import ch.qos.logback.core.model.processor.AppenderRefModelHandler;
import ch.qos.logback.core.model.processor.DefaultProcessor;
import ch.qos.logback.core.model.processor.InsertFromJNDIModelHandler;
import ch.qos.logback.core.model.processor.RefContainerDependencyAnalyser;
import ch.qos.logback.core.spi.ContextAware;
/**
* JoranConfigurator class adds rules specific to logback-classic.
*
* @author Ceki Gülcü
*/
public class JoranConfigurator extends JoranConfiguratorBase<ILoggingEvent> {
@Override
public void addElementSelectorAndActionAssociations(RuleStore rs) {
// add parent rules
super.addElementSelectorAndActionAssociations(rs);
rs.addRule(new ElementSelector("configuration"), () -> new ConfigurationAction());
rs.addRule(new ElementSelector("configuration/contextName"), () -> new ContextNameAction());
rs.addRule(new ElementSelector("configuration/contextListener"), () -> new LoggerContextListenerAction());
rs.addRule(new ElementSelector("configuration/insertFromJNDI"), () -> new InsertFromJNDIAction());
rs.addRule(new ElementSelector("configuration/logger"), () -> new LoggerAction());
rs.addRule(new ElementSelector("configuration/logger/level"), () -> new LevelAction());
rs.addRule(new ElementSelector("configuration/root"), () -> new RootLoggerAction());
rs.addRule(new ElementSelector("configuration/root/level"), () -> new LevelAction());
rs.addRule(new ElementSelector("configuration/logger/appender-ref"), () -> new AppenderRefAction());
rs.addRule(new ElementSelector("configuration/root/appender-ref"), () -> new AppenderRefAction());
rs.addRule(new ElementSelector("configuration/include"), () -> new IncludeAction());
rs.addRule(new ElementSelector("configuration/consolePlugin"), () -> new ConsolePluginAction());
rs.addRule(new ElementSelector("configuration/receiver"), () -> new ReceiverAction());
}
@Override
protected void sanityCheck(Model topModel) {
super.sanityCheck(topModel);
performCheck(new IfNestedWithinSecondPhaseElementSC(), topModel);
}
@Override
protected void addDefaultNestedComponentRegistryRules(DefaultNestedComponentRegistry registry) {
LogbackClassicDefaultNestedComponentRules.addDefaultNestedComponentRegistryRules(registry);
}
@Override
protected void addModelHandlerAssociations(DefaultProcessor defaultProcessor) {
super.addModelHandlerAssociations(defaultProcessor);
defaultProcessor.addHandler(ConfigurationModel.class, ConfigurationModelHandler::makeInstance);
defaultProcessor.addHandler(ContextNameModel.class, ContextNameModelHandler::makeInstance);
defaultProcessor.addHandler(LoggerContextListenerModel.class, LoggerContextListenerModelHandler::makeInstance);
defaultProcessor.addHandler(InsertFromJNDIModel.class, InsertFromJNDIModelHandler::makeInstance);
defaultProcessor.addHandler(AppenderModel.class, AppenderModelHandler::makeInstance);
defaultProcessor.addHandler(AppenderRefModel.class, AppenderRefModelHandler::makeInstance);
defaultProcessor.addHandler(RootLoggerModel.class, RootLoggerModelHandler::makeInstance);
defaultProcessor.addHandler(LoggerModel.class, LoggerModelHandler::makeInstance);
defaultProcessor.addHandler(LevelModel.class, LevelModelHandler::makeInstance);
defaultProcessor.addAnalyser(LoggerModel.class,
() -> new RefContainerDependencyAnalyser(context, LoggerModel.class));
defaultProcessor.addAnalyser(RootLoggerModel.class,
() -> new RefContainerDependencyAnalyser(context, RootLoggerModel.class));
defaultProcessor.addAnalyser(AppenderModel.class,
() -> new RefContainerDependencyAnalyser(context, AppenderModel.class));
defaultProcessor.addAnalyser(AppenderRefModel.class,
() -> new AppenderRefDependencyAnalyser(context));
sealModelFilters(defaultProcessor);
}
// The final filters in the two filter chain are rather crucial.
// They ensure that only Models attached to the firstPhaseFilter will
// be handled in the first phase and all models not previously handled
// in the second phase will be handled in a catch-all fallback case.
private void sealModelFilters(DefaultProcessor defaultProcessor) {
defaultProcessor.getPhaseOneFilter().denyAll();
defaultProcessor.getPhaseTwoFilter().allowAll();
}
}