001/**
002 * Logback: the reliable, generic, fast and flexible logging framework.
003 * Copyright (C) 1999-2022, 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.access.joran;
015
016import ch.qos.logback.access.joran.action.ConfigurationAction;
017import ch.qos.logback.access.model.ConfigurationModel;
018import ch.qos.logback.access.model.processor.ConfigurationModelHandler;
019import ch.qos.logback.access.model.processor.LogbackAccessDefaultNestedComponentRegistryRules;
020import ch.qos.logback.access.spi.IAccessEvent;
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.AppenderModel;
028import ch.qos.logback.core.model.AppenderRefModel;
029import ch.qos.logback.core.model.processor.AppenderModelHandler;
030import ch.qos.logback.core.model.processor.AppenderRefDependencyAnalyser;
031import ch.qos.logback.core.model.processor.AppenderRefModelHandler;
032import ch.qos.logback.core.model.processor.DefaultProcessor;
033import ch.qos.logback.core.model.processor.RefContainerDependencyAnalyser;
034
035/**
036 * This JoranConfiguratorclass adds rules specific to logback-access.
037 *
038 * @author Ceki Gülcü
039 */
040public class JoranConfigurator extends JoranConfiguratorBase<IAccessEvent> {
041
042    @Override
043    public void addElementSelectorAndActionAssociations(RuleStore rs) {
044        super.addElementSelectorAndActionAssociations(rs);
045
046        rs.addRule(new ElementSelector("configuration"), () -> new ConfigurationAction());
047        rs.addRule(new ElementSelector("configuration/appender-ref"), () -> new AppenderRefAction());
048        rs.addRule(new ElementSelector("configuration/include"), () -> new IncludeAction());
049    }
050
051    @Override
052    protected void addModelHandlerAssociations(DefaultProcessor defaultProcessor) {
053        super.addModelHandlerAssociations(defaultProcessor);
054        defaultProcessor.addHandler(ConfigurationModel.class, ConfigurationModelHandler::makeInstance);
055        defaultProcessor.addHandler(AppenderModel.class, AppenderModelHandler::makeInstance); 
056        defaultProcessor.addHandler(AppenderRefModel.class, AppenderRefModelHandler::makeInstance);
057
058        defaultProcessor.addAnalyser(AppenderModel.class, () -> 
059                new RefContainerDependencyAnalyser(context, AppenderModel.class));
060        defaultProcessor.addAnalyser(AppenderRefModel.class, () -> new AppenderRefDependencyAnalyser(context));
061
062        sealModelFilters(defaultProcessor);
063    }
064
065    // The final filters in the two filter chain are rather crucial.
066    // They ensure that only Models attached to the firstPhaseFilter will
067    // be handled in the first phase and all models not previously handled
068    // in the second phase will be handled in a catch-all fallback case.
069    private void sealModelFilters(DefaultProcessor defaultProcessor) {
070        defaultProcessor.getPhaseOneFilter().denyAll();
071        defaultProcessor.getPhaseTwoFilter().allowAll();
072    }
073
074    @Override
075    protected void addDefaultNestedComponentRegistryRules(DefaultNestedComponentRegistry registry) {
076        LogbackAccessDefaultNestedComponentRegistryRules.addDefaultNestedComponentRegistryRules(registry);    
077    }
078
079}