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.action;
15  
16  import org.xml.sax.Attributes;
17  
18  import ch.qos.logback.core.joran.spi.ActionException;
19  import ch.qos.logback.core.joran.spi.SaxEventInterpretationContext;
20  import ch.qos.logback.core.model.Model;
21  
22  public abstract class BaseModelAction extends Action {
23  
24      Model parentModel;
25      Model currentModel;
26      boolean inError = false;
27  
28      @Override
29      public void begin(SaxEventInterpretationContext saxEventInterpretationContext, String name, Attributes attributes)
30              throws ActionException {
31          parentModel = null;
32          inError = false;
33  
34          if (!validPreconditions(saxEventInterpretationContext, name, attributes)) {
35              inError = true;
36              return;
37          }
38  
39          currentModel = buildCurrentModel(saxEventInterpretationContext, name, attributes);
40          currentModel.setTag(name);
41          if (!saxEventInterpretationContext.isModelStackEmpty()) {
42              parentModel = saxEventInterpretationContext.peekModel();
43          }
44          final int lineNumber = getLineNumber(saxEventInterpretationContext);
45          currentModel.setLineNumber(lineNumber);
46          saxEventInterpretationContext.pushModel(currentModel);
47      }
48  
49      abstract protected Model buildCurrentModel(SaxEventInterpretationContext interpretationContext, String name,
50              Attributes attributes);
51  
52      /**
53       * Validate preconditions of this action.
54       * 
55       * By default, true is returned. Subclasses should override appropriately.
56       * 
57       * @param intercon
58       * @param name
59       * @param attributes
60       * @return
61       */
62      protected boolean validPreconditions(SaxEventInterpretationContext intercon, String name, Attributes attributes) {
63          return true;
64      }
65  
66      @Override
67      public void body(SaxEventInterpretationContext ec, String body) throws ActionException {
68          if(currentModel == null) {
69              throw new ActionException("current model is null. Is <configuration> element missing?");
70          }
71          currentModel.addText(body);
72      }
73  
74      @Override
75      public void end(SaxEventInterpretationContext saxEventInterpretationContext, String name) throws ActionException {
76          if (inError)
77              return;
78  
79          Model m = saxEventInterpretationContext.peekModel();
80  
81          if (m != currentModel) {
82              addWarn("The object "+ m +"] at the top of the stack differs from the model [" + currentModel.idString()
83                      + "] pushed earlier.");
84              addWarn("This is wholly unexpected.");
85          }
86  
87          // do not pop nor add to parent if there is no parent
88          if (parentModel != null) {
89              parentModel.addSubModel(currentModel);
90              saxEventInterpretationContext.popModel();
91          }
92      }
93  }