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.model.processor;
15  
16  import ch.qos.logback.core.Context;
17  import ch.qos.logback.core.joran.action.ActionUtil;
18  import ch.qos.logback.core.joran.action.ActionUtil.Scope;
19  import ch.qos.logback.core.model.DefineModel;
20  import ch.qos.logback.core.model.Model;
21  import ch.qos.logback.core.spi.LifeCycle;
22  import ch.qos.logback.core.spi.PropertyDefiner;
23  import ch.qos.logback.core.util.OptionHelper;
24  
25  /**
26   * Instantiate class for define property value. Get future property name and
27   * property definer class from attributes. Some property definer properties
28   * could be used. After defining put new property to context.
29   * 
30   * @author Aleksey Didik
31   */
32  public class DefineModelHandler extends ModelHandlerBase {
33  
34      boolean inError;
35      PropertyDefiner definer;
36      String propertyName;
37      Scope scope;
38  
39      public DefineModelHandler(Context context) {
40          super(context);
41      }
42  
43      static public DefineModelHandler makeInstance(Context context, ModelInterpretationContext ic) {
44          return new DefineModelHandler(context);
45      }
46  
47      @Override
48      protected Class<DefineModel> getSupportedModelClass() {
49          return DefineModel.class;
50      }
51  
52      @Override
53      public void handle(ModelInterpretationContext interpretationContext, Model model) throws ModelHandlerException {
54          definer = null;
55          inError = false;
56          propertyName = null;
57  
58          DefineModel defineModel = (DefineModel) model;
59  
60          propertyName = defineModel.getName();
61          String scopeStr = defineModel.getScopeStr();
62  
63          scope = ActionUtil.stringToScope(scopeStr);
64  
65          if (OptionHelper.isNullOrEmptyOrAllSpaces(propertyName)) {
66              addError("Missing property name for property definer. Near [" + model.getTag() + "] line "
67                      + model.getLineNumber());
68              inError = true;
69          }
70  
71          // read property definer class name
72          String className = defineModel.getClassName();
73          if (OptionHelper.isNullOrEmptyOrAllSpaces(className)) {
74              addError("Missing class name for property definer. Near [" + model.getTag() + "] line "
75                      + model.getLineNumber());
76              inError = true;
77          } else {
78              className = interpretationContext.getImport(className);
79          }
80  
81          if (inError)
82              return;
83  
84          // try to instantiate property definer
85          try {
86              addInfo("About to instantiate property definer of type [" + className + "]");
87              definer = (PropertyDefiner) OptionHelper.instantiateByClassName(className, PropertyDefiner.class, context);
88              definer.setContext(context);
89              interpretationContext.pushObject(definer);
90          } catch (Exception oops) {
91              inError = true;
92              addError("Could not create an PropertyDefiner of type [" + className + "].", oops);
93              throw new ModelHandlerException(oops);
94          }
95  
96      }
97  
98      /**
99       * Now property definer is initialized by all properties and we can put property
100      * value to context
101      */
102     @Override
103     public void postHandle(ModelInterpretationContext interpretationContext, Model model) throws ModelHandlerException {
104         if (inError) {
105             return;
106         }
107 
108         Object o = interpretationContext.peekObject();
109 
110         if (o != definer) {
111             addWarn("The object at the of the stack is not the property definer for property named [" + propertyName
112                     + "] pushed earlier.");
113         } else {
114             interpretationContext.popObject();
115             if (definer instanceof LifeCycle)
116                 ((LifeCycle) definer).start();
117 
118             // let's put defined property and value to context but only if it is
119             // not null
120             String propertyValue = definer.getPropertyValue();
121             if (propertyValue != null) {
122                 addInfo("Setting property " + propertyName + "=" + propertyValue + " in scope " + scope);
123                 ActionUtil.setProperty(interpretationContext, propertyName, propertyValue, scope);
124             }
125         }
126 
127     }
128 }