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.ElseAction; 018import ch.qos.logback.core.joran.conditional.IfAction; 019import ch.qos.logback.core.joran.conditional.ThenAction; 020import ch.qos.logback.core.joran.sanity.AppenderWithinAppenderSanityChecker; 021import ch.qos.logback.core.joran.sanity.SanityChecker; 022import ch.qos.logback.core.joran.spi.ElementSelector; 023import ch.qos.logback.core.joran.spi.RuleStore; 024import ch.qos.logback.core.joran.spi.SaxEventInterpretationContext; 025import ch.qos.logback.core.joran.spi.SaxEventInterpreter; 026import ch.qos.logback.core.model.*; 027import ch.qos.logback.core.model.conditional.ElseModel; 028import ch.qos.logback.core.model.conditional.IfModel; 029import ch.qos.logback.core.model.conditional.ThenModel; 030import ch.qos.logback.core.model.processor.*; 031import ch.qos.logback.core.model.processor.conditional.ElseModelHandler; 032import ch.qos.logback.core.model.processor.conditional.IfModelHandler; 033import ch.qos.logback.core.model.processor.conditional.ThenModelHandler; 034import ch.qos.logback.core.sift.SiftModelHandler; 035import ch.qos.logback.core.spi.ContextAware; 036 037// Based on 310985 revision 310985 as attested by http://tinyurl.com/8njps 038// see also http://tinyurl.com/c2rp5 039 040/** 041 * A JoranConfiguratorBase lays most of the groundwork for concrete 042 * configurators derived from it. Concrete configurators only need to implement 043 * the {@link #addElementSelectorAndActionAssociations} method. 044 * <p> 045 * A JoranConfiguratorBase instance should not be used more than once to 046 * configure a Context. 047 * 048 * @author Ceki Gülcü 049 */ 050abstract public class JoranConfiguratorBase<E> extends GenericXMLConfigurator { 051 052 @Override 053 protected void addElementSelectorAndActionAssociations(RuleStore rs) { 054 055 // is "*/variable" referenced in the docs? 056 rs.addRule(new ElementSelector("*/variable"), PropertyAction::new); 057 rs.addRule(new ElementSelector("*/property"), PropertyAction::new); 058 // substitutionProperty is deprecated 059 rs.addRule(new ElementSelector("*/substitutionProperty"), PropertyAction::new); 060 061 rs.addRule(new ElementSelector("configuration/import"), ImportAction::new); 062 063 064 rs.addRule(new ElementSelector("configuration/timestamp"), TimestampAction::new); 065 rs.addRule(new ElementSelector("configuration/shutdownHook"), ShutdownHookAction::new); 066 rs.addRule(new ElementSelector("configuration/sequenceNumberGenerator"), SequenceNumberGeneratorAction::new); 067 rs.addRule(new ElementSelector("configuration/serializeModel"), SerializeModelAction::new); 068 069 rs.addRule(new ElementSelector("configuration/define"), DefinePropertyAction::new); 070 rs.addRule(new ElementSelector("configuration/evaluator"), EventEvaluatorAction::new); 071 072 // the contextProperty pattern is deprecated. It is undocumented 073 // and will be dropped in future versions of logback 074 rs.addRule(new ElementSelector("configuration/contextProperty"), ContextPropertyAction::new); 075 076 rs.addRule(new ElementSelector("configuration/conversionRule"), ConversionRuleAction::new); 077 078 rs.addRule(new ElementSelector("configuration/statusListener"), StatusListenerAction::new); 079 080 rs.addRule(new ElementSelector("*/appender"), AppenderAction::new); 081 rs.addRule(new ElementSelector("configuration/appender/appender-ref"), AppenderRefAction::new); 082 rs.addRule(new ElementSelector("configuration/newRule"), NewRuleAction::new); 083 084 rs.addRule(new ElementSelector("*/param"), ParamAction::new); 085 086 // add if-then-else support 087 rs.addRule(new ElementSelector("*/if"), IfAction::new); 088 rs.addTransparentPathPart("if"); 089 rs.addRule(new ElementSelector("*/if/then"), ThenAction::new); 090 rs.addTransparentPathPart("then"); 091 rs.addRule(new ElementSelector("*/if/else"), ElseAction::new); 092 rs.addTransparentPathPart("else"); 093 094 rs.addRule(new ElementSelector("*/appender/sift"), SiftAction::new); 095 rs.addTransparentPathPart("sift"); 096 097 098 } 099 100 /** 101 * Perform sanity check and issue warning if necessary. 102 * 103 * @param topModel 104 */ 105 protected void sanityCheck(Model topModel) { 106 performCheck(new AppenderWithinAppenderSanityChecker(), topModel); 107 } 108 109 protected void performCheck(SanityChecker sc, Model model) { 110 if(sc instanceof ContextAware) 111 ((ContextAware) sc).setContext(context); 112 sc.check(model); 113 } 114 115 @Override 116 protected void setImplicitRuleSupplier(SaxEventInterpreter interpreter) { 117 interpreter.setImplicitActionSupplier( ImplicitModelAction::new ); 118 } 119 120 @Override 121 public void buildModelInterpretationContext() { 122 super.buildModelInterpretationContext(); 123 modelInterpretationContext.createAppenderBags(); 124 } 125 126 public SaxEventInterpretationContext getInterpretationContext() { 127 return saxEventInterpreter.getSaxEventInterpretationContext(); 128 } 129 130 @Override 131 protected void addModelHandlerAssociations(DefaultProcessor defaultProcessor) { 132 // code moved to ModelClassToModelHandlerLinkerBase 133 // the code below is inactive 134 defaultProcessor.addHandler(ImportModel.class, ImportModelHandler::makeInstance); 135 136 defaultProcessor.addHandler(ShutdownHookModel.class, ShutdownHookModelHandler::makeInstance); 137 defaultProcessor.addHandler(SequenceNumberGeneratorModel.class, SequenceNumberGeneratorModelHandler::makeInstance); 138 139 defaultProcessor.addHandler(EventEvaluatorModel.class, EventEvaluatorModelHandler::makeInstance); 140 defaultProcessor.addHandler(DefineModel.class, DefineModelHandler::makeInstance); 141 defaultProcessor.addHandler(IncludeModel.class, IncludeModelHandler::makeInstance); 142 143 144 defaultProcessor.addHandler(ParamModel.class, ParamModelHandler::makeInstance); 145 defaultProcessor.addHandler(PropertyModel.class, PropertyModelHandler::makeInstance); 146 defaultProcessor.addHandler(TimestampModel.class, TimestampModelHandler::makeInstance); 147 defaultProcessor.addHandler(StatusListenerModel.class, StatusListenerModelHandler::makeInstance); 148 defaultProcessor.addHandler(ImplicitModel.class, ImplicitModelHandler::makeInstance); 149 150 defaultProcessor.addHandler(IfModel.class, IfModelHandler::makeInstance); 151 defaultProcessor.addHandler(ThenModel.class, ThenModelHandler::makeInstance); 152 defaultProcessor.addHandler(ElseModel.class, ElseModelHandler::makeInstance); 153 154 defaultProcessor.addHandler(SiftModel.class, SiftModelHandler::makeInstance); 155 156 } 157 158}