    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    }