View Javadoc

1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements. See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache license, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License. You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the license for the specific language governing permissions and
15   * limitations under the license.
16   */
17  package org.apache.logging.log4j.core.impl;
18  
19  import java.io.Serializable;
20  
21  import sun.reflect.Reflection;
22  
23  /**
24   * Wraps and extends the concept of the JRE's final class {@link StackTraceElement} by adding more location information.
25   * <p>
26   * Complements a StackTraceElement with:
27   * <ul>
28   * <li>exact: whether the class was obtained via {@link Reflection#getCallerClass()}</li>
29   * <li>location: a classpath element or a jar</li>
30   * <li>version</li>
31   * </ul>
32   * </p>
33   */
34  public final class ExtendedStackTraceElement implements Serializable {
35  
36      private static final long serialVersionUID = -2171069569241280505L;
37  
38      private final ExtendedClassInfo extraClassInfo;
39  
40      private final StackTraceElement stackTraceElement;
41  
42      public ExtendedStackTraceElement(final StackTraceElement stackTraceElement, final ExtendedClassInfo extraClassInfo) {
43          this.stackTraceElement = stackTraceElement;
44          this.extraClassInfo = extraClassInfo;
45      }
46  
47      /**
48       * Called from Jackson for XML and JSON IO.
49       */
50      public ExtendedStackTraceElement(final String declaringClass, final String methodName, final String fileName,
51              final int lineNumber, final boolean exact, final String location, final String version) {
52          this(new StackTraceElement(declaringClass, methodName, fileName, lineNumber), new ExtendedClassInfo(exact,
53                  location, version));
54      }
55  
56      @Override
57      public boolean equals(final Object obj) {
58          if (this == obj) {
59              return true;
60          }
61          if (obj == null) {
62              return false;
63          }
64          if (!(obj instanceof ExtendedStackTraceElement)) {
65              return false;
66          }
67          final ExtendedStackTraceElement other = (ExtendedStackTraceElement) obj;
68          if (this.extraClassInfo == null) {
69              if (other.extraClassInfo != null) {
70                  return false;
71              }
72          } else if (!this.extraClassInfo.equals(other.extraClassInfo)) {
73              return false;
74          }
75          if (this.stackTraceElement == null) {
76              if (other.stackTraceElement != null) {
77                  return false;
78              }
79          } else if (!this.stackTraceElement.equals(other.stackTraceElement)) {
80              return false;
81          }
82          return true;
83      }
84  
85      public String getClassName() {
86          return this.stackTraceElement.getClassName();
87      }
88  
89      public boolean getExact() {
90          return this.extraClassInfo.getExact();
91      }
92  
93      public ExtendedClassInfo getExtraClassInfo() {
94          return this.extraClassInfo;
95      }
96  
97      public String getFileName() {
98          return this.stackTraceElement.getFileName();
99      }
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 }