001 /* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache license, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the license for the specific language governing permissions and 015 * limitations under the license. 016 */ 017 package org.apache.logging.log4j.core.impl; 018 019 import java.io.Serializable; 020 021 import sun.reflect.Reflection; 022 023 /** 024 * Wraps and extends the concept of the JRE's final class {@link StackTraceElement} by adding more location information. 025 * <p> 026 * Complements a StackTraceElement with: 027 * <ul> 028 * <li>exact: whether the class was obtained via {@link Reflection#getCallerClass()}</li> 029 * <li>location: a classpath element or a jar</li> 030 * <li>version</li> 031 * </ul> 032 * </p> 033 */ 034 public final class ExtendedStackTraceElement implements Serializable { 035 036 private static final long serialVersionUID = -2171069569241280505L; 037 038 private final ExtendedClassInfo extraClassInfo; 039 040 private final StackTraceElement stackTraceElement; 041 042 public ExtendedStackTraceElement(final StackTraceElement stackTraceElement, final ExtendedClassInfo extraClassInfo) { 043 this.stackTraceElement = stackTraceElement; 044 this.extraClassInfo = extraClassInfo; 045 } 046 047 /** 048 * Called from Jackson for XML and JSON IO. 049 */ 050 public ExtendedStackTraceElement(final String declaringClass, final String methodName, final String fileName, 051 final int lineNumber, final boolean exact, final String location, final String version) { 052 this(new StackTraceElement(declaringClass, methodName, fileName, lineNumber), new ExtendedClassInfo(exact, 053 location, version)); 054 } 055 056 @Override 057 public boolean equals(final Object obj) { 058 if (this == obj) { 059 return true; 060 } 061 if (obj == null) { 062 return false; 063 } 064 if (!(obj instanceof ExtendedStackTraceElement)) { 065 return false; 066 } 067 final ExtendedStackTraceElement other = (ExtendedStackTraceElement) obj; 068 if (this.extraClassInfo == null) { 069 if (other.extraClassInfo != null) { 070 return false; 071 } 072 } else if (!this.extraClassInfo.equals(other.extraClassInfo)) { 073 return false; 074 } 075 if (this.stackTraceElement == null) { 076 if (other.stackTraceElement != null) { 077 return false; 078 } 079 } else if (!this.stackTraceElement.equals(other.stackTraceElement)) { 080 return false; 081 } 082 return true; 083 } 084 085 public String getClassName() { 086 return this.stackTraceElement.getClassName(); 087 } 088 089 public boolean getExact() { 090 return this.extraClassInfo.getExact(); 091 } 092 093 public ExtendedClassInfo getExtraClassInfo() { 094 return this.extraClassInfo; 095 } 096 097 public String getFileName() { 098 return this.stackTraceElement.getFileName(); 099 } 100 101 public int getLineNumber() { 102 return this.stackTraceElement.getLineNumber(); 103 } 104 105 public String getLocation() { 106 return this.extraClassInfo.getLocation(); 107 } 108 109 public String getMethodName() { 110 return this.stackTraceElement.getMethodName(); 111 } 112 113 public StackTraceElement getStackTraceElement() { 114 return this.stackTraceElement; 115 } 116 117 public String getVersion() { 118 return this.extraClassInfo.getVersion(); 119 } 120 121 @Override 122 public int hashCode() { 123 final int prime = 31; 124 int result = 1; 125 result = prime * result + ((this.extraClassInfo == null) ? 0 : this.extraClassInfo.hashCode()); 126 result = prime * result + ((this.stackTraceElement == null) ? 0 : this.stackTraceElement.hashCode()); 127 return result; 128 } 129 130 public boolean isNativeMethod() { 131 return this.stackTraceElement.isNativeMethod(); 132 } 133 134 @Override 135 public String toString() { 136 final StringBuilder sb = new StringBuilder(); 137 sb.append(this.stackTraceElement); 138 sb.append(" "); 139 sb.append(this.extraClassInfo); 140 return sb.toString(); 141 } 142 }