001/* 002 * Logback: the reliable, generic, fast and flexible logging framework. 003 * Copyright (C) 1999-2026, 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 v2.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.classic.spi; 015 016import java.io.Serializable; 017import java.util.Arrays; 018 019public class ThrowableProxyVO implements IThrowableProxy, Serializable { 020 021 private static final long serialVersionUID = -773438177285807139L; 022 023 private String className; 024 private String overridingMessage; 025 private String message; 026 private int commonFramesCount; 027 private StackTraceElementProxy[] stackTraceElementProxyArray; 028 private IThrowableProxy cause; 029 private IThrowableProxy[] suppressed; 030 private boolean cyclic; 031 032 public String getMessage() { 033 return message; 034 } 035 /** 036 * Return the overriding message if any. This method returns null 037 * if there is no overriding message. 038 * 039 * <p>Overriding message exists only if the original throwable implementation overrides the toString() method.</p> 040 * 041 * @return the overriding message or null 042 * @since 1.5.22 043 */ 044 @Override 045 public String getOverridingMessage() { return overridingMessage;} 046 047 public String getClassName() { 048 return className; 049 } 050 051 public int getCommonFrames() { 052 return commonFramesCount; 053 } 054 055 public IThrowableProxy getCause() { 056 return cause; 057 } 058 059 public StackTraceElementProxy[] getStackTraceElementProxyArray() { 060 return stackTraceElementProxyArray; 061 } 062 063 public IThrowableProxy[] getSuppressed() { 064 return suppressed; 065 } 066 067 public boolean isCyclic() { 068 return cyclic; 069 } 070 071 /** 072 * Returns a new {@link ThrowableProxyVOBuilder} for constructing a 073 * {@link ThrowableProxyVO} field by field. 074 * 075 * <p>This is a supplement to {@link #build(IThrowableProxy)}, which copies 076 * an existing {@link IThrowableProxy} in one step.</p> 077 * 078 * @return a new builder instance 079 * @since 1.6.2 080 */ 081 public static ThrowableProxyVOBuilder builder() { 082 return new ThrowableProxyVOBuilder(); 083 } 084 085 // package-private setters used by ThrowableProxyVOBuilder 086 087 void setClassName(String className) { 088 this.className = className; 089 } 090 091 void setMessage(String message) { 092 this.message = message; 093 } 094 095 void setOverridingMessage(String overridingMessage) { 096 this.overridingMessage = overridingMessage; 097 } 098 099 void setCommonFramesCount(int commonFramesCount) { 100 this.commonFramesCount = commonFramesCount; 101 } 102 103 void setStackTraceElementProxyArray(StackTraceElementProxy[] stackTraceElementProxyArray) { 104 this.stackTraceElementProxyArray = stackTraceElementProxyArray; 105 } 106 107 void setCause(IThrowableProxy cause) { 108 this.cause = cause; 109 } 110 111 void setSuppressed(IThrowableProxy[] suppressed) { 112 this.suppressed = suppressed; 113 } 114 115 void setCyclic(boolean cyclic) { 116 this.cyclic = cyclic; 117 } 118 119 @Override 120 public int hashCode() { 121 final int prime = 31; 122 int result = 1; 123 result = prime * result + ((className == null) ? 0 : className.hashCode()); 124 return result; 125 } 126 127 @Override 128 public boolean equals(Object obj) { 129 if (this == obj) 130 return true; 131 if (obj == null) 132 return false; 133 if (getClass() != obj.getClass()) 134 return false; 135 final ThrowableProxyVO other = (ThrowableProxyVO) obj; 136 137 if (className == null) { 138 if (other.className != null) 139 return false; 140 } else if (!className.equals(other.className)) 141 return false; 142 143 if (!Arrays.equals(stackTraceElementProxyArray, other.stackTraceElementProxyArray)) 144 return false; 145 146 if (!Arrays.equals(suppressed, other.suppressed)) 147 return false; 148 149 if (cause == null) { 150 if (other.cause != null) 151 return false; 152 } else if (!cause.equals(other.cause)) 153 return false; 154 155 return true; 156 } 157 158 public static ThrowableProxyVO build(IThrowableProxy throwableProxy) { 159 if (throwableProxy == null) { 160 return null; 161 } 162 ThrowableProxyVO tpvo = new ThrowableProxyVO(); 163 tpvo.className = throwableProxy.getClassName(); 164 tpvo.message = throwableProxy.getMessage(); 165 tpvo.overridingMessage = throwableProxy.getOverridingMessage(); 166 tpvo.commonFramesCount = throwableProxy.getCommonFrames(); 167 tpvo.stackTraceElementProxyArray = throwableProxy.getStackTraceElementProxyArray(); 168 tpvo.cyclic = throwableProxy.isCyclic(); 169 170 IThrowableProxy cause = throwableProxy.getCause(); 171 if (cause != null) { 172 tpvo.cause = ThrowableProxyVO.build(cause); 173 } 174 IThrowableProxy[] suppressed = throwableProxy.getSuppressed(); 175 if (suppressed != null) { 176 tpvo.suppressed = new IThrowableProxy[suppressed.length]; 177 for (int i = 0; i < suppressed.length; i++) { 178 tpvo.suppressed[i] = ThrowableProxyVO.build(suppressed[i]); 179 } 180 } 181 182 return tpvo; 183 } 184}