001/** 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2022, QOS.ch. All rights reserved. 004 * 005 * This program and the accompanying materials are dual-licensed under 006 * either the terms of the Eclipse Public License v1.0 as published by 007 * the Eclipse Foundation 008 * 009 * or (per the licensee's choosing) 010 * 011 * under the terms of the GNU Lesser General Public License version 2.1 012 * as published by the Free Software Foundation. 013 */ 014package ch.qos.logback.core.model; 015 016import java.io.Serializable; 017import java.util.ArrayList; 018import java.util.List; 019import java.util.Objects; 020 021/** 022 * Abstract representation of configuration elements 023 * 024 * @author Ceki Gülcü 025 * @since 1.3.0 026 */ 027public class Model implements Serializable { 028 029 private static final long serialVersionUID = -797372668713068159L; 030 031 // this state should not be here but should be treated via listeners 032 // between processors and ModelHandlers 033 boolean handled = false; 034 boolean skipped = false; 035 036 String tag; 037 String bodyText; 038 int lineNumber; 039 040 List<Model> subModels = new ArrayList<>(); 041 042 static public Model duplicate(Model that) { 043 Model copy = that.makeNewInstance(); 044 copy.mirror(that); 045 for(Model m: that.subModels) { 046 Model duplicate = duplicate(m); 047 copy.subModels.add(duplicate); 048 } 049 return copy; 050 } 051 052 protected Model makeNewInstance() { 053 return new Model(); 054 } 055 056 protected void mirror(Model that) { 057 this.tag = that.tag; 058 this.bodyText = that.bodyText; 059 this.lineNumber = that.lineNumber; 060 } 061 062 063 public void markAsSkipped() { 064 skipped = true; 065 } 066 public void deepMarkAsSkipped() { 067 markAsSkipped(); 068 for(Model m: this.getSubModels()) { 069 m.deepMarkAsSkipped(); 070 } 071 } 072 /** 073 * The model can re-used at reconfiguration time. 074 * 075 * @since 1.3.0-alpha14 076 */ 077 void resetForReuse() { 078 this.handled = false; 079 this.skipped = false; 080 for(Model sub: subModels) { 081 sub.resetForReuse(); 082 } 083 } 084 085 public boolean isSkipped() { 086 return skipped; 087 } 088 089 public boolean isUnhandled() { 090 return !handled; 091 } 092 093 public boolean isHandled() { 094 return handled; 095 } 096 097 public void markAsHandled() { 098 handled = true; 099 } 100 101 102 103 104 public String getTag() { 105 return tag; 106 } 107 108 public void setTag(String tag) { 109 this.tag = tag; 110 } 111 112 public int getLineNumber() { 113 return lineNumber; 114 } 115 116 public void setLineNumber(int lineNumber) { 117 this.lineNumber = lineNumber; 118 } 119 120 public List<Model> getSubModels() { 121 return subModels; 122 } 123 124 public void addSubModel(Model m) { 125 subModels.add(m); 126 } 127 128 public String getBodyText() { 129 return bodyText; 130 } 131 132 public void addText(String bodytext) { 133 if (bodyText == null) 134 this.bodyText = bodytext; 135 else 136 this.bodyText += bodytext; 137 } 138 139 public String idString() { 140 return "<" + tag + "> at line " + lineNumber; 141 } 142 143 144 @Override 145 public int hashCode() { 146 return Objects.hash(bodyText, lineNumber, subModels, tag); 147 } 148 149 @Override 150 public boolean equals(Object obj) { 151 if (this == obj) 152 return true; 153 if (obj == null) 154 return false; 155 if (getClass() != obj.getClass()) 156 return false; 157 Model other = (Model) obj; 158 return Objects.equals(bodyText, other.bodyText) && lineNumber == other.lineNumber 159 && Objects.equals(subModels, other.subModels) && Objects.equals(tag, other.tag); 160 } 161 162 163 @Override 164 public String toString() { 165 return this.getClass().getSimpleName() + " [tag=" + tag + ", bodyText=" + bodyText + ", id="+hashCode()+"]"; 166 } 167 168}