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;
15  
16  import java.io.Serializable;
17  import java.util.ArrayList;
18  import java.util.List;
19  import java.util.Objects;
20  
21  /**
22   * Abstract representation of configuration elements
23   * 
24   * @author Ceki Gülcü
25   * @since 1.3.0
26   */
27  public class Model implements Serializable {
28  
29      private static final long serialVersionUID = -797372668713068159L;
30  
31      // this state should not be here but should be treated via listeners
32      // between processors and ModelHandlers
33      boolean handled = false;
34      boolean skipped = false;
35  
36      String tag;
37      String bodyText;
38      int lineNumber;
39  
40      List<Model> subModels = new ArrayList<>();
41  
42      static public Model duplicate(Model that) {
43          Model copy = that.makeNewInstance();
44          copy.mirror(that);
45          for(Model m: that.subModels) {
46              Model duplicate = duplicate(m);
47              copy.subModels.add(duplicate);
48          }
49          return copy;
50      }
51      
52      protected Model makeNewInstance() {
53          return new Model();
54      }
55      
56      protected void mirror(Model that) {
57          this.tag = that.tag;
58          this.bodyText = that.bodyText;
59          this.lineNumber = that.lineNumber;
60      }
61      
62      
63      public void markAsSkipped() {
64          skipped = true;
65      }
66      public void deepMarkAsSkipped() {
67          markAsSkipped();
68          for(Model m: this.getSubModels()) {
69              m.deepMarkAsSkipped();
70          }
71      }
72      /**
73       * The model can re-used at reconfiguration time.
74       * 
75       * @since 1.3.0-alpha14
76       */
77      void resetForReuse() {
78         this.handled = false;
79         this.skipped = false;
80         for(Model sub: subModels) {
81             sub.resetForReuse();
82         }
83      }
84      
85      public boolean isSkipped() {
86          return skipped;
87      }
88  
89      public boolean isUnhandled() {
90          return !handled;
91      }
92  
93      public boolean isHandled() {
94          return handled;
95      }
96  
97      public void markAsHandled() {
98          handled = true;
99      }
100 
101     public String getTag() {
102         return tag;
103     }
104 
105     public void setTag(String tag) {
106         this.tag = tag;
107     }
108 
109     public int getLineNumber() {
110         return lineNumber;
111     }
112 
113     public void setLineNumber(int lineNumber) {
114         this.lineNumber = lineNumber;
115     }
116 
117     public List<Model> getSubModels() {
118         return subModels;
119     }
120 
121     public void addSubModel(Model m) {
122         subModels.add(m);
123     }
124 
125     public String getBodyText() {
126         return bodyText;
127     }
128 
129     public void addText(String bodytext) {
130         if (bodyText == null)
131             this.bodyText = bodytext;
132         else
133             this.bodyText += bodytext;
134     }
135 
136     public String idString() {
137         return "<" + tag + "> at line " + lineNumber;
138     }
139 
140 
141     @Override
142     public int hashCode() {
143         return Objects.hash(bodyText, lineNumber, subModels, tag);
144     }
145 
146     @Override
147     public boolean equals(Object obj) {
148         if (this == obj)
149             return true;
150         if (obj == null)
151             return false;
152         if (getClass() != obj.getClass())
153             return false;
154         Model other = (Model) obj;
155         return Objects.equals(bodyText, other.bodyText) && lineNumber == other.lineNumber
156                 && Objects.equals(subModels, other.subModels) && Objects.equals(tag, other.tag);
157     }
158 
159     
160     @Override
161     public String toString() {
162         return this.getClass().getSimpleName() + " [tag=" + tag + ", bodyText=" + bodyText + ", id="+hashCode()+"]";
163     }
164 
165 }