001    /*
002     * $Id: Trace.java,v 1.5 2011/07/09 21:43:22 oboehm Exp $
003     *
004     * Copyright (c) 2010 by Oliver Boehm
005     *
006     * Licensed under the Apache License, Version 2.0 (the "License");
007     * you may not use this file except in compliance with the License.
008     * You may obtain a copy of the License at
009     *
010     *   http://www.apache.org/licenses/LICENSE-2.0
011     *
012     * Unless required by applicable law or agreed to in writing, software
013     * distributed under the License is distributed on an "AS IS" BASIS,
014     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express orimplied.
015     * See the License for the specific language governing permissions and
016     * limitations under the License.
017     *
018     * (c)reated 30.09.2010 by oliver (ob@oasd.de)
019     */
020    
021    package patterntesting.runtime.log;
022    
023    import org.aspectj.lang.JoinPoint;
024    import org.aspectj.lang.reflect.SourceLocation;
025    import org.slf4j.*;
026    
027    import patterntesting.runtime.util.*;
028    
029    /**
030     * This class works together with the (Abstract)TraceAspect to provide some
031     * kind of tracing information.
032     *
033     * @author oliver
034     * @since 1.0.3 (30.09.2010)
035     */
036    public final class Trace {
037    
038        private static final Logger log = LoggerFactory.getLogger(Trace.class);
039        private static final int indentStart = calibrateStacktraceDepth();
040    
041        static {
042            if (log.isTraceEnabled()) {
043                log.trace(Trace.class + " loaded");
044            } else if (log.isDebugEnabled()) {
045                log.info("to see more trace information set log level to TRACE for "
046                        + Trace.class.getName());
047            } else {
048                log.info("to see @TraceMe information you must set log level to DEBUG for "
049                        + Trace.class.getName());
050            }
051        }
052    
053        /** Utility class - no need to instantiate it. */
054        private Trace() {}
055    
056        private static int calibrateStacktraceDepth() {
057            StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
058            return stacktrace.length;
059        }
060    
061        /**
062         * Logs the trace with a start sign (">").
063         *
064         * @param joinpoint the joinpoint
065         */
066        public static void start(final JoinPoint joinpoint) {
067            if (log.isDebugEnabled()) {
068                int level = getIndentLevel();
069                trace(level, "> ", joinpoint, "");
070            }
071        }
072    
073        /**
074         * Logs the trace with a start sign ("<").
075         *
076         * @param joinpoint the joinpoint
077         */
078        public static void end(final JoinPoint joinpoint) {
079            if (log.isDebugEnabled()) {
080                int level = getIndentLevel();
081                trace(level, "< ", joinpoint, "");
082            }
083        }
084    
085        /**
086         * Logs the trace with a start sign ("<").
087         *
088         * @param joinpoint the joinpoint
089         * @param result the result
090         */
091        public static void end(final JoinPoint joinpoint, final Object result) {
092            if (log.isDebugEnabled()) {
093                int level = getIndentLevel();
094                trace(level, "< ", joinpoint, " = " + Converter.toShortString(result));
095            }
096        }
097    
098        /**
099         * Logs the thrown exception.
100         *
101         * @param joinpoint the joinpoint
102         * @param t the t
103         */
104        public static void throwing(final JoinPoint joinpoint, final Throwable t) {
105            if (log.isDebugEnabled()) {
106                int level = getIndentLevel();
107                trace(level, "<*", joinpoint, "");
108                trace(level, " *** ", t);
109            }
110        }
111    
112        /**
113         * Logs the trace with a start sign ("<").
114         *
115         * @param joinpoint the joinpoint
116         * @param suffix the suffix
117         */
118        public static void end(final JoinPoint joinpoint, final String suffix) {
119            if (log.isDebugEnabled()) {
120                int level = getIndentLevel();
121                trace(level, "< ", joinpoint, suffix);
122            }
123        }
124    
125        /**
126         * Logs the trace with a "|" sign.
127         *
128         * @param joinpoint the joinpoint
129         */
130        public static void trace(final JoinPoint joinpoint) {
131            if (log.isDebugEnabled()) {
132                int level = getIndentLevel();
133                trace(level, " | ", joinpoint, "");
134            }
135        }
136    
137        private static void trace(final int level, final String prefix, final JoinPoint joinpoint,
138                final String suffix) {
139            if (log.isTraceEnabled()) {
140                String loc = getLocation(joinpoint);
141                log.trace(indent(level) + prefix + JoinPointHelper.getAsLongString(joinpoint) + suffix
142                        + loc);
143            } else if (log.isDebugEnabled()) {
144                log.debug(indent(level) + prefix + JoinPointHelper.getAsShortString(joinpoint) + suffix);
145            }
146        }
147    
148        private static void trace(final int level, final String prefix, final Throwable t) {
149            if (log.isTraceEnabled()) {
150                log.trace(indent(level) + prefix, t);
151            } else if (log.isDebugEnabled()) {
152                log.debug(indent(level) + prefix + t);
153            }
154        }
155    
156        private static String indent(final int level) {
157            StringBuffer buffer = new StringBuffer();
158            for (int i = 0; i < level; i++) {
159                buffer.append("  ");
160            }
161            return buffer.toString();
162        }
163    
164        private static int getIndentLevel() {
165            StackTraceElement[] stacktrace = Thread.currentThread().getStackTrace();
166            return stacktrace.length - indentStart;
167        }
168    
169        private static String getLocation(final JoinPoint joinpoint) {
170            SourceLocation loc = joinpoint.getSourceLocation();
171            return " (" + loc.getFileName() + ":" + loc.getLine() + ")";
172        }
173    
174    }
175