1 /*
2  * Copyright (c) 2005, 2018, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */

25
26 package java.lang.management;
27
28 import javax.management.openmbean.CompositeData;
29 import sun.management.MonitorInfoCompositeData;
30
31 /**
32  * Information about an object monitor lock.  An object monitor is locked
33  * when entering a synchronization block or method on that object.
34  *
35  * <h3>MXBean Mapping</h3>
36  * {@code MonitorInfo} is mapped to a {@link CompositeData CompositeData}
37  * with attributes as specified in
38  * the {@link #from from} method.
39  *
40  * @author  Mandy Chung
41  * @since   1.6
42  */

43 public class MonitorInfo extends LockInfo {
44
45     private int    stackDepth;
46     private StackTraceElement stackFrame;
47
48     /**
49      * Construct a {@code MonitorInfo} object.
50      *
51      * @param className the fully qualified name of the class of the lock object.
52      * @param identityHashCode the {@link System#identityHashCode
53      *                         identity hash code} of the lock object.
54      * @param stackDepth the depth in the stack trace where the object monitor
55      *                   was locked.
56      * @param stackFrame the stack frame that locked the object monitor.
57      * @throws IllegalArgumentException if
58      *    {@code stackDepth} &ge; 0 but {@code stackFrame} is {@code null},
59      *    or {@code stackDepth} &lt; 0 but {@code stackFrame} is not
60      *       {@code null}.
61      */

62     public MonitorInfo(String className,
63                        int identityHashCode,
64                        int stackDepth,
65                        StackTraceElement stackFrame) {
66         super(className, identityHashCode);
67         if (stackDepth >= 0 && stackFrame == null) {
68             throw new IllegalArgumentException("Parameter stackDepth is " +
69                 stackDepth + " but stackFrame is null");
70         }
71         if (stackDepth < 0 && stackFrame != null) {
72             throw new IllegalArgumentException("Parameter stackDepth is " +
73                 stackDepth + " but stackFrame is not null");
74         }
75         this.stackDepth = stackDepth;
76         this.stackFrame = stackFrame;
77     }
78
79     /**
80      * Returns the depth in the stack trace where the object monitor
81      * was locked.  The depth is the index to the {@code StackTraceElement}
82      * array returned in the {@link ThreadInfo#getStackTrace} method.
83      *
84      * @return the depth in the stack trace where the object monitor
85      *         was locked, or a negative number if not available.
86      */

87     public int getLockedStackDepth() {
88         return stackDepth;
89     }
90
91     /**
92      * Returns the stack frame that locked the object monitor.
93      *
94      * @return {@code StackTraceElement} that locked the object monitor,
95      *         or {@code nullif not available.
96      */

97     public StackTraceElement getLockedStackFrame() {
98         return stackFrame;
99     }
100
101     /**
102      * Returns a {@code MonitorInfo} object represented by the
103      * given {@code CompositeData}.
104      * The given {@code CompositeData} must contain the following attributes
105      * as well as the attributes specified in the
106      * <a href="LockInfo.html#MappedType">
107      * mapped type</a> for the {@link LockInfo} class:
108      * <table class="striped" style="margin-left:2em">
109      * <caption style="display:none">The attributes and their types the given CompositeData contains</caption>
110      * <thead>
111      * <tr>
112      *   <th scope="col">Attribute Name</th>
113      *   <th scope="col">Type</th>
114      * </tr>
115      * </thead>
116      * <tbody style="text-align:left">
117      * <tr>
118      *   <th scope="row">lockedStackFrame</th>
119      *   <td><a href="ThreadInfo.html#stackTraceElement">
120      *       {@code CompositeData} for {@code StackTraceElement}</a> as specified
121      *       in {@link ThreadInfo#from(CompositeData)} method.
122      *   </td>
123      * </tr>
124      * <tr>
125      *   <th scope="row">lockedStackDepth</th>
126      *   <td>{@code java.lang.Integer}</td>
127      * </tr>
128      * </tbody>
129      * </table>
130      *
131      * @param cd {@code CompositeData} representing a {@code MonitorInfo}
132      *
133      * @throws IllegalArgumentException if {@code cd} does not
134      *   represent a {@code MonitorInfo} with the attributes described
135      *   above.
136      *
137      * @return a {@code MonitorInfo} object represented
138      *         by {@code cd} if {@code cd} is not {@code null};
139      *         {@code null} otherwise.
140      */

141     public static MonitorInfo from(CompositeData cd) {
142         if (cd == null) {
143             return null;
144         }
145
146         if (cd instanceof MonitorInfoCompositeData) {
147             return ((MonitorInfoCompositeData) cd).getMonitorInfo();
148         } else {
149             MonitorInfoCompositeData.validateCompositeData(cd);
150             String className = MonitorInfoCompositeData.getClassName(cd);
151             int identityHashCode = MonitorInfoCompositeData.getIdentityHashCode(cd);
152             int stackDepth = MonitorInfoCompositeData.getLockedStackDepth(cd);
153             StackTraceElement stackFrame = MonitorInfoCompositeData.getLockedStackFrame(cd);
154             return new MonitorInfo(className,
155                                    identityHashCode,
156                                    stackDepth,
157                                    stackFrame);
158         }
159     }
160
161 }
162