1. /*
  2. * Copyright 1999-2004 The Apache Software Foundation.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. package org.apache.commons.dbcp;
  17. import java.text.SimpleDateFormat;
  18. import java.util.ArrayList;
  19. import java.util.Date;
  20. import java.util.Iterator;
  21. import java.util.List;
  22. /**
  23. * Tracks db connection usage for recovering and reporting
  24. * abandoned db connections.
  25. *
  26. * The JDBC Connection, Statement, and ResultSet classes
  27. * extend this class.
  28. *
  29. * @author Glenn L. Nielsen
  30. * @version $Revision: 1.12 $ $Date: 2004/04/25 10:36:24 $
  31. * @deprecated This will be removed in a future version of DBCP.
  32. */
  33. public class AbandonedTrace {
  34. private static SimpleDateFormat format = new SimpleDateFormat
  35. ("'DBCP object created' yyyy-MM-dd HH:mm:ss " +
  36. "'by the following code was never closed:'");
  37. // DBCP AbandonedConfig
  38. private AbandonedConfig config = null;
  39. // Parent object
  40. private AbandonedTrace parent;
  41. // A stack trace of the code that created me (if in debug mode) **/
  42. private Exception createdBy;
  43. private long createdTime;
  44. // A list of objects created by children of this object
  45. private List trace = new ArrayList();
  46. // Last time this connection was used
  47. private long lastUsed = 0;
  48. /**
  49. * Create a new AbandonedTrace without config and
  50. * without doing abandoned tracing.
  51. */
  52. public AbandonedTrace() {
  53. init(parent);
  54. }
  55. /**
  56. * Construct a new AbandonedTrace with no parent object.
  57. *
  58. * @param AbandonedConfig
  59. */
  60. public AbandonedTrace(AbandonedConfig config) {
  61. this.config = config;
  62. init(parent);
  63. }
  64. /**
  65. * Construct a new AbandonedTrace with a parent object.
  66. *
  67. * @param AbandonedTrace parent object
  68. */
  69. public AbandonedTrace(AbandonedTrace parent) {
  70. this.config = parent.getConfig();
  71. init(parent);
  72. }
  73. /**
  74. * Initialize abandoned tracing for this object.
  75. *
  76. * @param AbandonedTrace parent object
  77. */
  78. private void init(AbandonedTrace parent) {
  79. if (parent != null) {
  80. parent.addTrace(this);
  81. }
  82. if (config == null) {
  83. return;
  84. }
  85. if (config.getLogAbandoned()) {
  86. createdBy = new Exception();
  87. createdTime = System.currentTimeMillis();
  88. }
  89. }
  90. /**
  91. * Get the abandoned config for this object.
  92. *
  93. * @return AbandonedConfig for this object
  94. */
  95. protected AbandonedConfig getConfig() {
  96. return config;
  97. }
  98. /**
  99. * Get the last time this object was used in ms.
  100. *
  101. * @return long time in ms
  102. */
  103. protected long getLastUsed() {
  104. if (parent != null) {
  105. return parent.getLastUsed();
  106. }
  107. return lastUsed;
  108. }
  109. /**
  110. * Set the time this object was last used to the
  111. * current time in ms.
  112. */
  113. protected void setLastUsed() {
  114. if (parent != null) {
  115. parent.setLastUsed();
  116. } else {
  117. lastUsed = System.currentTimeMillis();
  118. }
  119. }
  120. /**
  121. * Set the time in ms this object was last used.
  122. *
  123. * @param long time in ms
  124. */
  125. protected void setLastUsed(long time) {
  126. if (parent != null) {
  127. parent.setLastUsed(time);
  128. } else {
  129. lastUsed = time;
  130. }
  131. }
  132. /**
  133. * If logAbandoned=true generate a stack trace
  134. * for this object then add this object to the parent
  135. * object trace list.
  136. */
  137. protected void setStackTrace() {
  138. if (config == null) {
  139. return;
  140. }
  141. if (config.getLogAbandoned()) {
  142. createdBy = new Exception();
  143. createdTime = System.currentTimeMillis();
  144. }
  145. if (parent != null) {
  146. parent.addTrace(this);
  147. }
  148. }
  149. /**
  150. * Add an object to the list of objects being
  151. * traced.
  152. *
  153. * @param AbandonedTrace object to add
  154. */
  155. protected void addTrace(AbandonedTrace trace) {
  156. synchronized(this) {
  157. this.trace.add(trace);
  158. }
  159. setLastUsed();
  160. }
  161. /**
  162. * Clear the list of objects being traced by this
  163. * object.
  164. */
  165. protected synchronized void clearTrace() {
  166. if (this.trace != null) {
  167. this.trace.clear();
  168. }
  169. }
  170. /**
  171. * Get a list of objects being traced by this object.
  172. *
  173. * @return List of objects
  174. */
  175. protected List getTrace() {
  176. return trace;
  177. }
  178. /**
  179. * If logAbandoned=true, print a stack trace of the code that
  180. * created this object.
  181. */
  182. public void printStackTrace() {
  183. if (createdBy != null) {
  184. System.out.println(format.format(new Date(createdTime)));
  185. createdBy.printStackTrace(System.out);
  186. }
  187. synchronized(this) {
  188. Iterator it = this.trace.iterator();
  189. while (it.hasNext()) {
  190. AbandonedTrace at = (AbandonedTrace)it.next();
  191. at.printStackTrace();
  192. }
  193. }
  194. }
  195. /**
  196. * Remove a child object this object is tracing.
  197. *
  198. * @param AbandonedTrace object to remvoe
  199. */
  200. protected synchronized void removeTrace(AbandonedTrace trace) {
  201. if (this.trace != null) {
  202. this.trace.remove(trace);
  203. }
  204. }
  205. }