001/* 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2026, 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 v2.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 } 064 065 066 @Override 067 protected void sanityCheck(Model topModel) { 068 super.sanityCheck(topModel); 069 performCheck(new IfNestedWithinSecondPhaseElementSC(), topModel); 070 } 071 072 @Override 073 protected void addDefaultNestedComponentRegistryRules(DefaultNestedComponentRegistry registry) { 074 LogbackClassicDefaultNestedComponentRules.addDefaultNestedComponentRegistryRules(registry); 075 } 076 077 private JoranConfigurator makeAnotherInstance() { 078 JoranConfigurator jc = new JoranConfigurator(); 079 jc.setContext(context); 080 return jc; 081 } 082 083 public void buildModelInterpretationContext() { 084 super.buildModelInterpretationContext(); 085 this.modelInterpretationContext.setConfiguratorSupplier( () -> this.makeAnotherInstance() ); 086 } 087 088 @Override 089 protected void addModelHandlerAssociations(DefaultProcessor defaultProcessor) { 090 ModelClassToModelHandlerLinker m = new ModelClassToModelHandlerLinker(context); 091 m.setConfigurationModelHandlerFactoryMethod(ConfigurationModelHandlerFull::makeInstance); 092 m.link(defaultProcessor); 093 } 094 095 096 // The final filters in the two filter chain are rather crucial. 097 // They ensure that only Models attached to the firstPhaseFilter will 098 // be handled in the first phase and all models not previously handled 099 // in the second phase will be handled in a catch-all fallback case. 100 private void sealModelFilters(DefaultProcessor defaultProcessor) { 101 defaultProcessor.getPhaseOneFilter().denyAll(); 102 defaultProcessor.getPhaseTwoFilter().allowAll(); 103 } 104 105}