View Javadoc
1   /**
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2015, 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.classic.joran;
15  
16  import ch.qos.logback.classic.joran.action.ConfigurationAction;
17  import ch.qos.logback.classic.joran.action.ConsolePluginAction;
18  import ch.qos.logback.classic.joran.action.ContextNameAction;
19  import ch.qos.logback.classic.joran.action.InsertFromJNDIAction;
20  import ch.qos.logback.classic.joran.action.JMXConfiguratorAction;
21  import ch.qos.logback.classic.joran.action.LevelAction;
22  import ch.qos.logback.classic.joran.action.LoggerAction;
23  import ch.qos.logback.classic.joran.action.LoggerContextListenerAction;
24  import ch.qos.logback.classic.joran.action.ReceiverAction;
25  import ch.qos.logback.classic.joran.action.RootLoggerAction;
26  import ch.qos.logback.classic.model.ConfigurationModel;
27  import ch.qos.logback.classic.model.ContextNameModel;
28  import ch.qos.logback.classic.model.LevelModel;
29  import ch.qos.logback.classic.model.LoggerContextListenerModel;
30  import ch.qos.logback.classic.model.LoggerModel;
31  import ch.qos.logback.classic.model.RootLoggerModel;
32  import ch.qos.logback.classic.model.processor.ConfigurationModelHandler;
33  import ch.qos.logback.classic.model.processor.ContextNameModelHandler;
34  import ch.qos.logback.classic.model.processor.LevelModelHandler;
35  import ch.qos.logback.classic.model.processor.LoggerContextListenerModelHandler;
36  import ch.qos.logback.classic.model.processor.LoggerModelHandler;
37  import ch.qos.logback.classic.model.processor.RootLoggerModelHandler;
38  import ch.qos.logback.classic.spi.ILoggingEvent;
39  import ch.qos.logback.classic.spi.PlatformInfo;
40  import ch.qos.logback.classic.util.DefaultNestedComponentRules;
41  import ch.qos.logback.core.Context;
42  import ch.qos.logback.core.joran.JoranConfiguratorBase;
43  import ch.qos.logback.core.joran.action.AppenderRefAction;
44  import ch.qos.logback.core.joran.action.IncludeAction;
45  import ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry;
46  import ch.qos.logback.core.joran.spi.ElementSelector;
47  import ch.qos.logback.core.joran.spi.RuleStore;
48  import ch.qos.logback.core.model.AppenderModel;
49  import ch.qos.logback.core.model.AppenderRefModel;
50  import ch.qos.logback.core.model.DefineModel;
51  import ch.qos.logback.core.model.EventEvaluatorModel;
52  import ch.qos.logback.core.model.ImplicitModel;
53  import ch.qos.logback.core.model.ImportModel;
54  import ch.qos.logback.core.model.IncludeModel;
55  import ch.qos.logback.core.model.Model;
56  import ch.qos.logback.core.model.ParamModel;
57  import ch.qos.logback.core.model.PropertyModel;
58  import ch.qos.logback.core.model.ShutdownHookModel;
59  import ch.qos.logback.core.model.TimestampModel;
60  import ch.qos.logback.core.model.conditional.ElseModel;
61  import ch.qos.logback.core.model.conditional.IfModel;
62  import ch.qos.logback.core.model.conditional.ThenModel;
63  import ch.qos.logback.core.model.processor.AppenderModelHandler;
64  import ch.qos.logback.core.model.processor.AppenderRefDependencyAnalyser;
65  import ch.qos.logback.core.model.processor.AppenderRefModelHandler;
66  import ch.qos.logback.core.model.processor.ChainedModelFilter;
67  import ch.qos.logback.core.model.processor.DefaultProcessor;
68  import ch.qos.logback.core.model.processor.ModelInterpretationContext;
69  import ch.qos.logback.core.model.processor.RefContainerDependencyAnalyser;
70  
71  /**
72   * JoranConfigurator class adds rules specific to logback-classic.
73   *
74   * @author Ceki Gülcü
75   */
76  public class JoranConfigurator extends JoranConfiguratorBase<ILoggingEvent> {
77  
78      @Override
79      public void addInstanceRules(RuleStore rs) {
80          // add parent rules
81          super.addInstanceRules(rs);
82  
83          rs.addRule(new ElementSelector("configuration"), () -> new ConfigurationAction());
84  
85          rs.addRule(new ElementSelector("configuration/contextName"), () -> new ContextNameAction());
86          rs.addRule(new ElementSelector("configuration/contextListener"), () -> new LoggerContextListenerAction());
87          rs.addRule(new ElementSelector("configuration/insertFromJNDI"), () -> new InsertFromJNDIAction());
88  
89          rs.addRule(new ElementSelector("configuration/logger"), () -> new LoggerAction());
90          rs.addRule(new ElementSelector("configuration/logger/level"), () -> new LevelAction());
91  
92          rs.addRule(new ElementSelector("configuration/root"), () -> new RootLoggerAction());
93          rs.addRule(new ElementSelector("configuration/root/level"), () -> new LevelAction());
94          rs.addRule(new ElementSelector("configuration/logger/appender-ref"), () -> new AppenderRefAction());
95          rs.addRule(new ElementSelector("configuration/root/appender-ref"), () -> new AppenderRefAction());
96          
97          if (PlatformInfo.hasJMXObjectName()) {
98              rs.addRule(new ElementSelector("configuration/jmxConfigurator"), () -> new JMXConfiguratorAction());
99          }
100         rs.addRule(new ElementSelector("configuration/include"), () -> new IncludeAction());
101 
102         rs.addRule(new ElementSelector("configuration/consolePlugin"), () -> new ConsolePluginAction());
103 
104         rs.addRule(new ElementSelector("configuration/receiver"), () -> new ReceiverAction());
105 
106     }
107 
108     @Override
109     protected void addDefaultNestedComponentRegistryRules(DefaultNestedComponentRegistry registry) {
110         DefaultNestedComponentRules.addDefaultNestedComponentRegistryRules(registry);
111     }
112 
113     @Override
114     protected DefaultProcessor buildDefaultProcessor(Context context, ModelInterpretationContext mic) {
115         DefaultProcessor defaultProcessor = super.buildDefaultProcessor(context, mic);
116         defaultProcessor.addHandler(ConfigurationModel.class, ConfigurationModelHandler::makeInstance);
117         defaultProcessor.addHandler(ContextNameModel.class, ContextNameModelHandler::makeInstance);
118         defaultProcessor.addHandler(LoggerContextListenerModel.class, LoggerContextListenerModelHandler::makeInstance);
119 
120         defaultProcessor.addHandler(AppenderModel.class, AppenderModelHandler::makeInstance);
121         defaultProcessor.addHandler(AppenderRefModel.class, AppenderRefModelHandler::makeInstance);
122         defaultProcessor.addHandler(RootLoggerModel.class, RootLoggerModelHandler::makeInstance);
123         defaultProcessor.addHandler(LoggerModel.class, LoggerModelHandler::makeInstance);
124         defaultProcessor.addHandler(LevelModel.class, LevelModelHandler::makeInstance);
125 
126         defaultProcessor.addAnalyser(LoggerModel.class, new RefContainerDependencyAnalyser(context, LoggerModel.class));
127 
128         defaultProcessor.addAnalyser(RootLoggerModel.class,
129                 new RefContainerDependencyAnalyser(context, RootLoggerModel.class));
130 
131         defaultProcessor.addAnalyser(AppenderModel.class,
132                 new RefContainerDependencyAnalyser(context, AppenderModel.class));
133 
134         defaultProcessor.addAnalyser(AppenderRefModel.class, new AppenderRefDependencyAnalyser(context));
135 
136         injectModelFilters(defaultProcessor);
137 
138         return defaultProcessor;
139     }
140 
141     private void injectModelFilters(DefaultProcessor defaultProcessor) {
142         @SuppressWarnings("unchecked")
143         Class<? extends Model>[] importModelClasses = new Class[] { ImportModel.class };
144 
145         @SuppressWarnings("unchecked")
146         Class<? extends Model>[] variableDefinitionModelClasses = new Class[] { ContextNameModel.class,
147                 DefineModel.class, PropertyModel.class, TimestampModel.class, ParamModel.class };
148 
149         @SuppressWarnings("unchecked")
150         Class<? extends Model>[] implicitModelClasses = new Class[] { ImplicitModel.class };
151 
152         @SuppressWarnings("unchecked")
153         Class<? extends Model>[] otherFirstPhaseModelClasses = new Class[] { ConfigurationModel.class,
154                 EventEvaluatorModel.class, LoggerContextListenerModel.class, ShutdownHookModel.class,
155                 IncludeModel.class, IfModel.class, ThenModel.class, ElseModel.class};
156 
157         // MOTE: AppenderModelHandler is delayed to second phase
158 
159         ChainedModelFilter fistPhaseDefintionFilter = new ChainedModelFilter();
160         for (Class<? extends Model> modelClass : importModelClasses)
161             fistPhaseDefintionFilter.allow(modelClass);
162         for (Class<? extends Model> modelClass : variableDefinitionModelClasses)
163             fistPhaseDefintionFilter.allow(modelClass);
164         for (Class<? extends Model> modelClass : otherFirstPhaseModelClasses)
165             fistPhaseDefintionFilter.allow(modelClass);
166         for (Class<? extends Model> modelClass : implicitModelClasses)
167             fistPhaseDefintionFilter.allow(modelClass);
168 
169         fistPhaseDefintionFilter.denyAll();
170         defaultProcessor.setPhaseOneFilter(fistPhaseDefintionFilter);
171 
172         ChainedModelFilter secondPhaseDefinitionFilter = new ChainedModelFilter();
173         secondPhaseDefinitionFilter.allowAll();
174 
175         defaultProcessor.setPhaseTwoFilter(secondPhaseDefinitionFilter);
176 
177     }
178 
179 }