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.*;
017import ch.qos.logback.classic.joran.sanity.IfNestedWithinSecondPhaseElementSC;
018import ch.qos.logback.classic.model.processor.ConfigurationModelHandlerFull;
019import ch.qos.logback.classic.model.processor.LogbackClassicDefaultNestedComponentRules;
020import ch.qos.logback.classic.spi.ILoggingEvent;
021import ch.qos.logback.core.joran.JoranConfiguratorBase;
022import ch.qos.logback.core.joran.action.AppenderRefAction;
023import ch.qos.logback.core.joran.action.IncludeAction;
024import ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry;
025import ch.qos.logback.core.joran.spi.ElementSelector;
026import ch.qos.logback.core.joran.spi.RuleStore;
027import ch.qos.logback.core.model.Model;
028import ch.qos.logback.core.model.processor.DefaultProcessor;
029
030/**
031 * JoranConfigurator class adds rules specific to logback-classic.
032 *
033 * @author Ceki Gülcü
034 */
035public class JoranConfigurator extends JoranConfiguratorBase<ILoggingEvent> {
036
037
038
039    @Override
040    public void addElementSelectorAndActionAssociations(RuleStore rs) {
041        // add parent rules
042        super.addElementSelectorAndActionAssociations(rs);
043
044        rs.addRule(new ElementSelector("configuration"), () -> new ConfigurationAction());
045
046        rs.addRule(new ElementSelector("configuration/contextName"), () -> new ContextNameAction());
047        rs.addRule(new ElementSelector("configuration/contextListener"), () -> new LoggerContextListenerAction());
048        rs.addRule(new ElementSelector("configuration/insertFromJNDI"), () -> new InsertFromJNDIAction());
049
050        rs.addRule(new ElementSelector("configuration/logger"), () -> new LoggerAction());
051        rs.addRule(new ElementSelector("configuration/logger/level"), () -> new LevelAction());
052
053        rs.addRule(new ElementSelector("configuration/root"), () -> new RootLoggerAction());
054        rs.addRule(new ElementSelector("configuration/root/level"), () -> new LevelAction());
055        rs.addRule(new ElementSelector("configuration/logger/appender-ref"), () -> new AppenderRefAction());
056        rs.addRule(new ElementSelector("configuration/root/appender-ref"), () -> new AppenderRefAction());
057
058        rs.addRule(new ElementSelector("configuration/include"), () -> new IncludeAction());
059        rs.addRule(new ElementSelector("configuration/propertiesConfigurator"), () -> new PropertiesConfiguratorAction());
060
061        rs.addRule(new ElementSelector("configuration/consolePlugin"), () -> new ConsolePluginAction());
062
063        rs.addRule(new ElementSelector("configuration/receiver"), () -> new ReceiverAction());
064
065
066    }
067
068
069    @Override
070    protected void sanityCheck(Model topModel) {
071        super.sanityCheck(topModel);
072        performCheck(new IfNestedWithinSecondPhaseElementSC(), topModel);
073    }
074
075    @Override
076    protected void addDefaultNestedComponentRegistryRules(DefaultNestedComponentRegistry registry) {
077        LogbackClassicDefaultNestedComponentRules.addDefaultNestedComponentRegistryRules(registry);
078    }
079
080    private JoranConfigurator makeAnotherInstance() {
081        JoranConfigurator jc = new JoranConfigurator();
082        jc.setContext(context);
083        return jc;
084    }
085
086    public void buildModelInterpretationContext() {
087        super.buildModelInterpretationContext();
088        this.modelInterpretationContext.setConfiguratorSupplier(  () -> this.makeAnotherInstance() );
089    }
090
091    @Override
092    protected void addModelHandlerAssociations(DefaultProcessor defaultProcessor) {
093        ModelClassToModelHandlerLinker m = new ModelClassToModelHandlerLinker(context);
094        m.setConfigurationModelHandlerFactoryMethod(ConfigurationModelHandlerFull::makeInstance2);
095        m.link(defaultProcessor);
096    }
097
098
099    // The final filters in the two filter chain are rather crucial.
100    // They ensure that only Models attached to the firstPhaseFilter will
101    // be handled in the first phase and all models not previously handled
102    // in the second phase will be handled in a catch-all fallback case.
103    private void sealModelFilters(DefaultProcessor defaultProcessor) {
104        defaultProcessor.getPhaseOneFilter().denyAll();
105        defaultProcessor.getPhaseTwoFilter().allowAll();
106    }
107
108}