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.core.joran; 015 016import ch.qos.logback.core.joran.action.*; 017import ch.qos.logback.core.joran.conditional.*; 018import ch.qos.logback.core.joran.sanity.AppenderWithinAppenderSanityChecker; 019import ch.qos.logback.core.joran.sanity.SanityChecker; 020import ch.qos.logback.core.joran.spi.ElementSelector; 021import ch.qos.logback.core.joran.spi.RuleStore; 022import ch.qos.logback.core.joran.spi.SaxEventInterpretationContext; 023import ch.qos.logback.core.joran.spi.SaxEventInterpreter; 024import ch.qos.logback.core.model.*; 025import ch.qos.logback.core.model.processor.*; 026import ch.qos.logback.core.spi.ContextAware; 027 028// Based on 310985 revision 310985 as attested by http://tinyurl.com/8njps 029// see also http://tinyurl.com/c2rp5 030 031/** 032 * A JoranConfiguratorBase lays most of the groundwork for concrete 033 * configurators derived from it. Concrete configurators only need to implement 034 * the {@link #addElementSelectorAndActionAssociations} method. 035 * <p> 036 * A JoranConfiguratorBase instance should not be used more than once to 037 * configure a Context. 038 * 039 * @author Ceki Gülcü 040 */ 041abstract public class JoranConfiguratorBase<E> extends GenericXMLConfigurator { 042 043 @Override 044 protected void addElementSelectorAndActionAssociations(RuleStore rs) { 045 046 // is "*/variable" referenced in the docs? 047 rs.addRule(new ElementSelector("*/variable"), PropertyAction::new); 048 rs.addRule(new ElementSelector("*/property"), PropertyAction::new); 049 // substitutionProperty is deprecated 050 rs.addRule(new ElementSelector("*/substitutionProperty"), PropertyAction::new); 051 052 rs.addRule(new ElementSelector("configuration/import"), ImportAction::new); 053 054 055 rs.addRule(new ElementSelector("configuration/timestamp"), TimestampAction::new); 056 rs.addRule(new ElementSelector("configuration/shutdownHook"), ShutdownHookAction::new); 057 rs.addRule(new ElementSelector("configuration/sequenceNumberGenerator"), SequenceNumberGeneratorAction::new); 058 rs.addRule(new ElementSelector("configuration/serializeModel"), SerializeModelAction::new); 059 060 rs.addRule(new ElementSelector("configuration/define"), DefinePropertyAction::new); 061 rs.addRule(new ElementSelector("configuration/evaluator"), EventEvaluatorAction::new); 062 063 // the contextProperty pattern is deprecated. It is undocumented 064 // and will be dropped in future versions of logback 065 rs.addRule(new ElementSelector("configuration/contextProperty"), ContextPropertyAction::new); 066 067 rs.addRule(new ElementSelector("configuration/conversionRule"), ConversionRuleAction::new); 068 069 rs.addRule(new ElementSelector("configuration/statusListener"), StatusListenerAction::new); 070 071 rs.addRule(new ElementSelector("*/appender"), AppenderAction::new); 072 rs.addRule(new ElementSelector("configuration/appender/appender-ref"), AppenderRefAction::new); 073 rs.addRule(new ElementSelector("configuration/newRule"), NewRuleAction::new); 074 075 rs.addRule(new ElementSelector("*/param"), ParamAction::new); 076 077 // add if-then-else support 078 rs.addRule(new ElementSelector("*/condition"), ByPropertiesConditionAction::new); 079 rs.addRule(new ElementSelector("*/if"), IfAction::new); 080 rs.addTransparentPathPart("if"); 081 rs.addRule(new ElementSelector("*/if/then"), ThenAction::new); 082 rs.addTransparentPathPart("then"); 083 rs.addRule(new ElementSelector("*/if/else"), ElseAction::new); 084 rs.addTransparentPathPart("else"); 085 086 rs.addRule(new ElementSelector("*/appender/sift"), SiftAction::new); 087 rs.addTransparentPathPart("sift"); 088 089 090 } 091 092 /** 093 * Perform sanity check and issue warning if necessary. 094 * 095 * @param topModel 096 */ 097 protected void sanityCheck(Model topModel) { 098 performCheck(new AppenderWithinAppenderSanityChecker(), topModel); 099 } 100 101 protected void performCheck(SanityChecker sc, Model model) { 102 if(sc instanceof ContextAware) 103 ((ContextAware) sc).setContext(context); 104 sc.check(model); 105 } 106 107 @Override 108 protected void setImplicitRuleSupplier(SaxEventInterpreter interpreter) { 109 interpreter.setImplicitActionSupplier( ImplicitModelAction::new ); 110 } 111 112 @Override 113 public void buildModelInterpretationContext() { 114 super.buildModelInterpretationContext(); 115 modelInterpretationContext.createAppenderBags(); 116 } 117 118 public SaxEventInterpretationContext getInterpretationContext() { 119 return saxEventInterpreter.getSaxEventInterpretationContext(); 120 } 121 122 @Override 123 protected void addModelHandlerAssociations(DefaultProcessor defaultProcessor) { 124 // Please note that code previously here moved to ModelClassToModelHandlerLinkerBase 125 } 126 127}