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 067 /** 068 * The model can re-used at reconfiguration time. 069 * 070 * @since 1.3.0-alpha14 071 */ 072 void resetForReuse() { 073 this.handled = false; 074 this.skipped = false; 075 for(Model sub: subModels) { 076 sub.resetForReuse(); 077 } 078 } 079 080 public boolean isSkipped() { 081 return skipped; 082 } 083 084 public boolean isUnhandled() { 085 return !handled; 086 } 087 088 public boolean isHandled() { 089 return handled; 090 } 091 092 public void markAsHandled() { 093 handled = true; 094 } 095 096 097 public String getTag() { 098 return tag; 099 } 100 101 public void setTag(String tag) { 102 this.tag = tag; 103 } 104 105 public int getLineNumber() { 106 return lineNumber; 107 } 108 109 public void setLineNumber(int lineNumber) { 110 this.lineNumber = lineNumber; 111 } 112 113 public List<Model> getSubModels() { 114 return subModels; 115 } 116 117 public void addSubModel(Model m) { 118 subModels.add(m); 119 } 120 121 public String getBodyText() { 122 return bodyText; 123 } 124 125 public void addText(String bodytext) { 126 if (bodyText == null) 127 this.bodyText = bodytext; 128 else 129 this.bodyText += bodytext; 130 } 131 132 public String idString() { 133 return "<" + tag + "> at line " + lineNumber; 134 } 135 136 137 @Override 138 public int hashCode() { 139 return Objects.hash(bodyText, lineNumber, subModels, tag); 140 } 141 142 @Override 143 public boolean equals(Object obj) { 144 if (this == obj) 145 return true; 146 if (obj == null) 147 return false; 148 if (getClass() != obj.getClass()) 149 return false; 150 Model other = (Model) obj; 151 return Objects.equals(bodyText, other.bodyText) && lineNumber == other.lineNumber 152 && Objects.equals(subModels, other.subModels) && Objects.equals(tag, other.tag); 153 } 154 155 156 @Override 157 public String toString() { 158 return this.getClass().getSimpleName() + " [tag=" + tag + ", bodyText=" + bodyText + ", id="+hashCode()+"]"; 159 } 160 161}