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.joran;
015
016import ch.qos.logback.classic.joran.action.ConfigurationAction;
017import ch.qos.logback.classic.joran.action.ConsolePluginAction;
018import ch.qos.logback.classic.joran.action.ContextNameAction;
019import ch.qos.logback.classic.joran.action.InsertFromJNDIAction;
020import ch.qos.logback.classic.joran.action.LevelAction;
021import ch.qos.logback.classic.joran.action.LoggerAction;
022import ch.qos.logback.classic.joran.action.LoggerContextListenerAction;
023import ch.qos.logback.classic.joran.action.ReceiverAction;
024import ch.qos.logback.classic.joran.action.RootLoggerAction;
025import ch.qos.logback.classic.model.ConfigurationModel;
026import ch.qos.logback.classic.model.ContextNameModel;
027import ch.qos.logback.classic.model.LevelModel;
028import ch.qos.logback.classic.model.LoggerContextListenerModel;
029import ch.qos.logback.classic.model.LoggerModel;
030import ch.qos.logback.classic.model.RootLoggerModel;
031import ch.qos.logback.classic.model.processor.ConfigurationModelHandler;
032import ch.qos.logback.classic.model.processor.ContextNameModelHandler;
033import ch.qos.logback.classic.model.processor.LevelModelHandler;
034import ch.qos.logback.classic.model.processor.LogbackClassicDefaultNestedComponentRules;
035import ch.qos.logback.classic.model.processor.LoggerContextListenerModelHandler;
036import ch.qos.logback.classic.model.processor.LoggerModelHandler;
037import ch.qos.logback.classic.model.processor.RootLoggerModelHandler;
038import ch.qos.logback.classic.spi.ILoggingEvent;
039import ch.qos.logback.classic.spi.PlatformInfo;
040import ch.qos.logback.core.joran.JoranConfiguratorBase;
041import ch.qos.logback.core.joran.action.AppenderRefAction;
042import ch.qos.logback.core.joran.action.IncludeAction;
043import ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry;
044import ch.qos.logback.core.joran.spi.ElementSelector;
045import ch.qos.logback.core.joran.spi.RuleStore;
046import ch.qos.logback.core.model.AppenderModel;
047import ch.qos.logback.core.model.AppenderRefModel;
048import ch.qos.logback.core.model.processor.AppenderModelHandler;
049import ch.qos.logback.core.model.processor.AppenderRefDependencyAnalyser;
050import ch.qos.logback.core.model.processor.AppenderRefModelHandler;
051import ch.qos.logback.core.model.processor.DefaultProcessor;
052import ch.qos.logback.core.model.processor.RefContainerDependencyAnalyser;
053
054/**
055 * JoranConfigurator class adds rules specific to logback-classic.
056 *
057 * @author Ceki Gülcü
058 */
059public class JoranConfigurator extends JoranConfiguratorBase<ILoggingEvent> {
060
061    @Override
062    public void addElementSelectorAndActionAssociations(RuleStore rs) {
063        // add parent rules
064        super.addElementSelectorAndActionAssociations(rs);
065
066        rs.addRule(new ElementSelector("configuration"), () -> new ConfigurationAction());
067
068        rs.addRule(new ElementSelector("configuration/contextName"), () -> new ContextNameAction());
069        rs.addRule(new ElementSelector("configuration/contextListener"), () -> new LoggerContextListenerAction());
070        rs.addRule(new ElementSelector("configuration/insertFromJNDI"), () -> new InsertFromJNDIAction());
071
072        rs.addRule(new ElementSelector("configuration/logger"), () -> new LoggerAction());
073        rs.addRule(new ElementSelector("configuration/logger/level"), () -> new LevelAction());
074
075        rs.addRule(new ElementSelector("configuration/root"), () -> new RootLoggerAction());
076        rs.addRule(new ElementSelector("configuration/root/level"), () -> new LevelAction());
077        rs.addRule(new ElementSelector("configuration/logger/appender-ref"), () -> new AppenderRefAction());
078        rs.addRule(new ElementSelector("configuration/root/appender-ref"), () -> new AppenderRefAction());
079
080        rs.addRule(new ElementSelector("configuration/include"), () -> new IncludeAction());
081
082        rs.addRule(new ElementSelector("configuration/consolePlugin"), () -> new ConsolePluginAction());
083
084        rs.addRule(new ElementSelector("configuration/receiver"), () -> new ReceiverAction());
085
086    }
087
088    @Override
089    protected void addDefaultNestedComponentRegistryRules(DefaultNestedComponentRegistry registry) {
090        LogbackClassicDefaultNestedComponentRules.addDefaultNestedComponentRegistryRules(registry);
091    }
092
093    @Override
094    protected void addModelHandlerAssociations(DefaultProcessor defaultProcessor) {
095        super.addModelHandlerAssociations(defaultProcessor);
096        defaultProcessor.addHandler(ConfigurationModel.class, ConfigurationModelHandler::makeInstance);
097        defaultProcessor.addHandler(ContextNameModel.class, ContextNameModelHandler::makeInstance);
098        defaultProcessor.addHandler(LoggerContextListenerModel.class, LoggerContextListenerModelHandler::makeInstance);
099
100        defaultProcessor.addHandler(AppenderModel.class, AppenderModelHandler::makeInstance);
101        defaultProcessor.addHandler(AppenderRefModel.class, AppenderRefModelHandler::makeInstance);
102        defaultProcessor.addHandler(RootLoggerModel.class, RootLoggerModelHandler::makeInstance);
103        defaultProcessor.addHandler(LoggerModel.class, LoggerModelHandler::makeInstance);
104        defaultProcessor.addHandler(LevelModel.class, LevelModelHandler::makeInstance);
105
106        defaultProcessor.addAnalyser(LoggerModel.class, 
107                () -> new RefContainerDependencyAnalyser(context, LoggerModel.class));
108
109        defaultProcessor.addAnalyser(RootLoggerModel.class,
110                () -> new RefContainerDependencyAnalyser(context, RootLoggerModel.class));
111
112        defaultProcessor.addAnalyser(AppenderModel.class,
113                () -> new RefContainerDependencyAnalyser(context, AppenderModel.class));
114
115        defaultProcessor.addAnalyser(AppenderRefModel.class, 
116                () -> new AppenderRefDependencyAnalyser(context));
117
118        sealModelFilters(defaultProcessor);
119    }
120
121
122    // The final filters in the two filter chain are rather crucial.
123    // They ensure that only Models attached to the firstPhaseFilter will
124    // be handled in the first phase and all models not previously handled
125    // in the second phase will be handled in a catch-all fallback case.
126    private void sealModelFilters(DefaultProcessor defaultProcessor) {
127        defaultProcessor.getPhaseOneFilter().denyAll();
128        defaultProcessor.getPhaseTwoFilter().allowAll();
129    }
130
131}