1   /*
2    * Logback: the reliable, generic, fast and flexible logging framework.
3    * Copyright (C) 1999-2026, 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 v2.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  
15  package ch.qos.logback.core.model.processor;
16  
17  import static ch.qos.logback.core.joran.action.Action.CLASS_ATTRIBUTE;
18  
19  import java.util.Map;
20  
21  import ch.qos.logback.core.Context;
22  import ch.qos.logback.core.CoreConstants;
23  import ch.qos.logback.core.boolex.EventEvaluator;
24  import ch.qos.logback.core.joran.spi.DefaultNestedComponentRegistry;
25  import ch.qos.logback.core.model.EventEvaluatorModel;
26  import ch.qos.logback.core.model.Model;
27  import ch.qos.logback.core.spi.LifeCycle;
28  import ch.qos.logback.core.util.OptionHelper;
29  
30  public class EventEvaluatorModelHandler extends ModelHandlerBase {
31  
32      EventEvaluator<?> evaluator;
33      boolean inError = false;
34  
35      public EventEvaluatorModelHandler(Context context) {
36          super(context);
37      }
38  
39      static public ModelHandlerBase makeInstance(Context context, ModelInterpretationContext ic) {
40          return new EventEvaluatorModelHandler(context);
41      }
42  
43      @Override
44      protected Class<EventEvaluatorModel> getSupportedModelClass() {
45          return EventEvaluatorModel.class;
46      }
47  
48      @Override
49      public void handle(ModelInterpretationContext intercon, Model model) throws ModelHandlerException {
50          EventEvaluatorModel eem = (EventEvaluatorModel) model;
51  
52          String className = eem.getClassName();
53          if (OptionHelper.isNullOrEmptyOrAllSpaces(className)) {
54              String defaultClassName = defaultClassName(intercon, eem);
55              if (OptionHelper.isNullOrEmptyOrAllSpaces(defaultClassName)) {
56                  inError = true;
57                  addError("Mandatory \"" + CLASS_ATTRIBUTE + "\" attribute missing for <evaluator>");
58                  addError("No default classname could be found.");
59                  return;
60              } else {
61                  addInfo("Assuming default evaluator class [" + defaultClassName + "]");
62                  className = defaultClassName;
63              }
64          } else {
65              className = intercon.getImport(className);
66          }
67  
68          String evaluatorName = intercon.subst(eem.getName());
69          try {
70              evaluator = (EventEvaluator<?>) OptionHelper.instantiateByClassName(className,
71                      ch.qos.logback.core.boolex.EventEvaluator.class, context);
72              evaluator.setContext(this.context);
73              evaluator.setName(evaluatorName);
74              intercon.pushObject(evaluator);
75  
76          } catch (Exception oops) {
77              inError = true;
78              addError("Could not create evaluator of type " + className + "].", oops);
79          }
80  
81      }
82  
83      private String defaultClassName(ModelInterpretationContext mic, EventEvaluatorModel model) {
84          DefaultNestedComponentRegistry registry = mic.getDefaultNestedComponentRegistry();
85          return registry.findDefaultComponentTypeByTag(model.getTag());
86      }
87  
88      @Override
89      public void postHandle(ModelInterpretationContext intercon, Model model) throws ModelHandlerException {
90          if (inError) {
91              return;
92          }
93  
94          if (evaluator instanceof LifeCycle) {
95              ((LifeCycle) evaluator).start();
96              addInfo("Starting evaluator named [" + evaluator.getName() + "]");
97          }
98  
99          Object o = intercon.peekObject();
100 
101         if (o != evaluator) {
102             addWarn("The object on the top the of the stack is not the evaluator pushed earlier.");
103         } else {
104             intercon.popObject();
105 
106             try {
107                 @SuppressWarnings("unchecked")
108                 Map<String, EventEvaluator<?>> evaluatorMap = (Map<String, EventEvaluator<?>>) context
109                         .getObject(CoreConstants.EVALUATOR_MAP);
110                 if (evaluatorMap == null) {
111                     addError("Could not find EvaluatorMap");
112                 } else {
113                     evaluatorMap.put(evaluator.getName(), evaluator);
114                 }
115             } catch (Exception ex) {
116                 addError("Could not set evaluator named [" + evaluator + "].", ex);
117             }
118         }
119     }
120 
121 }