View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2022, QOS.ch. All rights reserved.
4    *
5    * This program and the accompanying materials are dual-licensed under
6    * either the terms of the Eclipse Public License v1.0 as published by
7    * the Eclipse Foundation
8    *
9    *   or (per the licensee's choosing)
10   *
11   * under the terms of the GNU Lesser General Public License version 2.1
12   * as published by the Free Software Foundation.
13   */
14  package ch.qos.logback.core.joran;
15  
16  import ch.qos.logback.core.joran.action.*;
17  import ch.qos.logback.core.joran.conditional.ElseAction;
18  import ch.qos.logback.core.joran.conditional.IfAction;
19  import ch.qos.logback.core.joran.conditional.ThenAction;
20  import ch.qos.logback.core.joran.sanity.AppenderWithinAppenderSanityChecker;
21  import ch.qos.logback.core.joran.sanity.SanityChecker;
22  import ch.qos.logback.core.joran.spi.ElementSelector;
23  import ch.qos.logback.core.joran.spi.RuleStore;
24  import ch.qos.logback.core.joran.spi.SaxEventInterpretationContext;
25  import ch.qos.logback.core.joran.spi.SaxEventInterpreter;
26  import ch.qos.logback.core.model.*;
27  import ch.qos.logback.core.model.conditional.ElseModel;
28  import ch.qos.logback.core.model.conditional.IfModel;
29  import ch.qos.logback.core.model.conditional.ThenModel;
30  import ch.qos.logback.core.model.processor.*;
31  import ch.qos.logback.core.model.processor.conditional.ElseModelHandler;
32  import ch.qos.logback.core.model.processor.conditional.IfModelHandler;
33  import ch.qos.logback.core.model.processor.conditional.ThenModelHandler;
34  import ch.qos.logback.core.sift.SiftModelHandler;
35  import ch.qos.logback.core.spi.ContextAware;
36  
37  // Based on 310985 revision 310985 as attested by http://tinyurl.com/8njps
38  // see also http://tinyurl.com/c2rp5
39  
40  /**
41   * A JoranConfiguratorBase lays most of the groundwork for concrete
42   * configurators derived from it. Concrete configurators only need to implement
43   * the {@link #addElementSelectorAndActionAssociations} method.
44   * <p>
45   * A JoranConfiguratorBase instance should not be used more than once to
46   * configure a Context.
47   *
48   * @author Ceki G&uuml;lc&uuml;
49   */
50  abstract public class JoranConfiguratorBase<E> extends GenericXMLConfigurator {
51  
52      @Override
53      protected void addElementSelectorAndActionAssociations(RuleStore rs) {
54  
55          // is "*/variable" referenced in the docs?
56          rs.addRule(new ElementSelector("*/variable"), PropertyAction::new);
57          rs.addRule(new ElementSelector("*/property"),  PropertyAction::new);
58          // substitutionProperty is deprecated
59          rs.addRule(new ElementSelector("*/substitutionProperty"),  PropertyAction::new);
60  
61          rs.addRule(new ElementSelector("configuration/import"), ImportAction::new);
62          
63  
64          rs.addRule(new ElementSelector("configuration/timestamp"),  TimestampAction::new);
65          rs.addRule(new ElementSelector("configuration/shutdownHook"),  ShutdownHookAction::new);
66          rs.addRule(new ElementSelector("configuration/sequenceNumberGenerator"),  SequenceNumberGeneratorAction::new);
67          rs.addRule(new ElementSelector("configuration/serializeModel"),  SerializeModelAction::new);
68  
69          rs.addRule(new ElementSelector("configuration/define"),  DefinePropertyAction::new);
70          rs.addRule(new ElementSelector("configuration/evaluator"),  EventEvaluatorAction::new);
71  
72          // the contextProperty pattern is deprecated. It is undocumented
73          // and will be dropped in future versions of logback
74          rs.addRule(new ElementSelector("configuration/contextProperty"),  ContextPropertyAction::new);
75  
76          rs.addRule(new ElementSelector("configuration/conversionRule"),  ConversionRuleAction::new);
77  
78          rs.addRule(new ElementSelector("configuration/statusListener"),  StatusListenerAction::new);
79  
80          rs.addRule(new ElementSelector("*/appender"),  AppenderAction::new);
81          rs.addRule(new ElementSelector("configuration/appender/appender-ref"),  AppenderRefAction::new);
82          rs.addRule(new ElementSelector("configuration/newRule"),  NewRuleAction::new);
83  
84          rs.addRule(new ElementSelector("*/param"),  ParamAction::new);
85  
86          // add if-then-else support
87          rs.addRule(new ElementSelector("*/if"),  IfAction::new);
88          rs.addTransparentPathPart("if");
89          rs.addRule(new ElementSelector("*/if/then"),  ThenAction::new);
90          rs.addTransparentPathPart("then");
91          rs.addRule(new ElementSelector("*/if/else"),  ElseAction::new);
92          rs.addTransparentPathPart("else");
93          
94          rs.addRule(new ElementSelector("*/appender/sift"),  SiftAction::new);
95          rs.addTransparentPathPart("sift");
96          
97          
98      }
99  
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 }