1 /*
2  * Copyright 2008-2019 by Emeric Vernat
3  *
4  *     This file is part of Java Melody.
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */

18 package net.bull.javamelody.internal.model;
19
20 import java.io.Serializable;
21 import java.sql.Connection;
22 import java.util.ArrayList;
23 import java.util.Arrays;
24 import java.util.Collections;
25 import java.util.Date;
26 import java.util.List;
27
28 import net.bull.javamelody.Parameter;
29
30 /**
31  * Informations sur l'ouverture d'une connexion jdbc (heure et stack trace).
32  * Cet état est celui d'une connexion à un instant t.
33  * Les instances sont sérialisables pour pouvoir être transmises au serveur de collecte.
34  * @author Emeric Vernat
35  */

36 public class ConnectionInformations implements Serializable {
37     private static final long serialVersionUID = -6063966419161604125L;
38     private static final String OWN_PACKAGE = ConnectionInformations.class.getName().substring(0,
39             ConnectionInformations.class.getName().lastIndexOf('.'));
40     private static final boolean CONNECTIONS_STACK_TRACES_DISABLED = Parameter.CONNECTIONS_STACK_TRACES_DISABLED
41             .getValueAsBoolean();
42     private final long openingTime;
43     private final StackTraceElement[] openingStackTrace;
44     private final long threadId;
45
46     public ConnectionInformations() {
47         super();
48         this.openingTime = System.currentTimeMillis();
49         final Thread currentThread = Thread.currentThread();
50         if (CONNECTIONS_STACK_TRACES_DISABLED) {
51             this.openingStackTrace = null;
52         } else {
53             this.openingStackTrace = currentThread.getStackTrace();
54         }
55         this.threadId = currentThread.getId();
56     }
57
58     public static int getUniqueIdOfConnection(Connection connection) {
59         // ce hashCode est normalement implémenté par l'adresse mémoire de l'objet
60         // qui est donc unique
61         return System.identityHashCode(connection);
62     }
63
64     public Date getOpeningDate() {
65         return new Date(openingTime);
66     }
67
68     public List<StackTraceElement> getOpeningStackTrace() {
69         if (openingStackTrace == null) {
70             return Collections.emptyList();
71         }
72         final List<StackTraceElement> stackTrace = new ArrayList<>(
73                 Arrays.asList(openingStackTrace));
74         // on enlève les premiers éléments qui sont forcément ceux de javamelody
75         // (Thread.getStackTrace(), constructeur ConnectionInformations,
76         // JdbcWrapper.createConnectionProxy, appelant de createConnectionProxy...)
77         stackTrace.remove(0);
78         while (stackTrace.get(0).getClassName().startsWith(OWN_PACKAGE)) {
79             stackTrace.remove(0);
80         }
81         return stackTrace;
82     }
83
84     public long getThreadId() {
85         return threadId;
86     }
87
88     /** {@inheritDoc} */
89     @Override
90     public String toString() {
91         return getClass().getSimpleName() + "[openingDate=" + getOpeningDate() + ", threadId="
92                 + getThreadId() + ']';
93     }
94 }
95