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&uuml;lc&uuml;
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}