001: /*
002: * Distributed as part of c3p0 v.0.9.1.2
003: *
004: * Copyright (C) 2005 Machinery For Change, Inc.
005: *
006: * Author: Steve Waldman <swaldman@mchange.com>
007: *
008: * This library is free software; you can redistribute it and/or modify
009: * it under the terms of the GNU Lesser General Public License version 2.1, as
010: * published by the Free Software Foundation.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
015: * GNU Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public License
018: * along with this software; see the file LICENSE. If not, write to the
019: * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
020: * Boston, MA 02111-1307, USA.
021: */
022:
023: package com.mchange.v2.debug;
024:
025: import java.text.*;
026: import java.util.*;
027: import com.mchange.lang.ThrowableUtils;
028:
029: public class ThreadNameStackTraceRecorder {
030: final static String NL = System.getProperty("line.separator",
031: "\r\n");
032:
033: Set set = new HashSet();
034:
035: String dumpHeader;
036: String stackTraceHeader;
037:
038: public ThreadNameStackTraceRecorder(String dumpHeader) {
039: this (dumpHeader, "Debug Stack Trace.");
040: }
041:
042: public ThreadNameStackTraceRecorder(String dumpHeader,
043: String stackTraceHeader) {
044: this .dumpHeader = dumpHeader;
045: this .stackTraceHeader = stackTraceHeader;
046: }
047:
048: public synchronized Object record() {
049: Record r = new Record(stackTraceHeader);
050: set.add(r);
051: return r;
052: }
053:
054: public synchronized void remove(Object rec) {
055: set.remove(rec);
056: }
057:
058: public synchronized int size() {
059: return set.size();
060: }
061:
062: public synchronized String getDump() {
063: return getDump(null);
064: }
065:
066: public synchronized String getDump(String locationSpecificNote) {
067: DateFormat df = new SimpleDateFormat(
068: "dd-MMMM-yyyy HH:mm:ss.SSSS");
069:
070: StringBuffer sb = new StringBuffer(2047);
071: sb.append(NL);
072: sb
073: .append("----------------------------------------------------");
074: sb.append(NL);
075: sb.append(dumpHeader);
076: sb.append(NL);
077: if (locationSpecificNote != null) {
078: sb.append(locationSpecificNote);
079: sb.append(NL);
080: }
081: boolean first = true;
082: for (Iterator ii = set.iterator(); ii.hasNext();) {
083: if (first)
084: first = false;
085: else {
086: sb.append("---");
087: sb.append(NL);
088: }
089:
090: Record r = (Record) ii.next();
091: sb.append(df.format(new Date(r.time)));
092: sb.append(" --> Thread Name: ");
093: sb.append(r.threadName);
094: sb.append(NL);
095: sb.append("Stack Trace: ");
096: sb.append(ThrowableUtils.extractStackTrace(r.stackTrace));
097: }
098: sb
099: .append("----------------------------------------------------");
100: sb.append(NL);
101: return sb.toString();
102: }
103:
104: private final static class Record implements Comparable {
105: long time;
106: String threadName;
107: Throwable stackTrace;
108:
109: Record(String sth) {
110: this .time = System.currentTimeMillis();
111: this .threadName = Thread.currentThread().getName();
112: this .stackTrace = new Exception(sth);
113: }
114:
115: public int compareTo(Object o) {
116: Record oo = (Record) o;
117: if (this .time > oo.time)
118: return 1;
119: else if (this .time < oo.time)
120: return -1;
121: else {
122: int mine = System.identityHashCode(this );
123: int yours = System.identityHashCode(oo);
124: if (mine > yours)
125: return 1;
126: else if (mine < yours)
127: return -1;
128: return 0;
129: }
130: }
131: }
132: }
|