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 /**
022 * Wraps and extends the concept of the JRE's final class {@link StackTraceElement} by adding more location information.
023 * <p>
024 * Complements a StackTraceElement with:
025 * </p>
026 * <ul>
027 * <li>exact: whether the class was obtained via {@link sun.reflect.Reflection#getCallerClass(int)}</li>
028 * <li>location: a classpath element or a jar</li>
029 * <li>version</li>
030 * </ul>
031 */
032 public final class ExtendedStackTraceElement implements Serializable {
033
034 private static final long serialVersionUID = -2171069569241280505L;
035
036 private final ExtendedClassInfo extraClassInfo;
037
038 private final StackTraceElement stackTraceElement;
039
040 public ExtendedStackTraceElement(final StackTraceElement stackTraceElement, final ExtendedClassInfo extraClassInfo) {
041 this.stackTraceElement = stackTraceElement;
042 this.extraClassInfo = extraClassInfo;
043 }
044
045 /**
046 * Called from Jackson for XML and JSON IO.
047 */
048 public ExtendedStackTraceElement(final String declaringClass, final String methodName, final String fileName,
049 final int lineNumber, final boolean exact, final String location, final String version) {
050 this(new StackTraceElement(declaringClass, methodName, fileName, lineNumber), new ExtendedClassInfo(exact,
051 location, version));
052 }
053
054 @Override
055 public boolean equals(final Object obj) {
056 if (this == obj) {
057 return true;
058 }
059 if (obj == null) {
060 return false;
061 }
062 if (!(obj instanceof ExtendedStackTraceElement)) {
063 return false;
064 }
065 final ExtendedStackTraceElement other = (ExtendedStackTraceElement) obj;
066 if (this.extraClassInfo == null) {
067 if (other.extraClassInfo != null) {
068 return false;
069 }
070 } else if (!this.extraClassInfo.equals(other.extraClassInfo)) {
071 return false;
072 }
073 if (this.stackTraceElement == null) {
074 if (other.stackTraceElement != null) {
075 return false;
076 }
077 } else if (!this.stackTraceElement.equals(other.stackTraceElement)) {
078 return false;
079 }
080 return true;
081 }
082
083 public String getClassName() {
084 return this.stackTraceElement.getClassName();
085 }
086
087 public boolean getExact() {
088 return this.extraClassInfo.getExact();
089 }
090
091 public ExtendedClassInfo getExtraClassInfo() {
092 return this.extraClassInfo;
093 }
094
095 public String getFileName() {
096 return this.stackTraceElement.getFileName();
097 }
098
099 public int getLineNumber() {
100 return this.stackTraceElement.getLineNumber();
101 }
102
103 public String getLocation() {
104 return this.extraClassInfo.getLocation();
105 }
106
107 public String getMethodName() {
108 return this.stackTraceElement.getMethodName();
109 }
110
111 public StackTraceElement getStackTraceElement() {
112 return this.stackTraceElement;
113 }
114
115 public String getVersion() {
116 return this.extraClassInfo.getVersion();
117 }
118
119 @Override
120 public int hashCode() {
121 final int prime = 31;
122 int result = 1;
123 result = prime * result + ((this.extraClassInfo == null) ? 0 : this.extraClassInfo.hashCode());
124 result = prime * result + ((this.stackTraceElement == null) ? 0 : this.stackTraceElement.hashCode());
125 return result;
126 }
127
128 public boolean isNativeMethod() {
129 return this.stackTraceElement.isNativeMethod();
130 }
131
132 @Override
133 public String toString() {
134 final StringBuilder sb = new StringBuilder();
135 sb.append(this.stackTraceElement);
136 sb.append(" ");
137 sb.append(this.extraClassInfo);
138 return sb.toString();
139 }
140 }