1/*
2 * Copyright (c) 2005, 2012, 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
26package sun.management;
27
28import java.lang.management.MonitorInfo;
29import javax.management.openmbean.CompositeType;
30import javax.management.openmbean.CompositeData;
31import javax.management.openmbean.CompositeDataSupport;
32import javax.management.openmbean.OpenDataException;
33import java.util.Set;
34
35/**
36 * A CompositeData for MonitorInfo for the local management support.
37 * This class avoids the performance penalty paid to the
38 * construction of a CompositeData use in the local case.
39 */
40public class MonitorInfoCompositeData extends LazyCompositeData {
41    private final MonitorInfo lock;
42
43    private MonitorInfoCompositeData(MonitorInfo mi) {
44        this.lock = mi;
45    }
46
47    public MonitorInfo getMonitorInfo() {
48        return lock;
49    }
50
51    public static CompositeData toCompositeData(MonitorInfo mi) {
52        MonitorInfoCompositeData micd = new MonitorInfoCompositeData(mi);
53        return micd.getCompositeData();
54    }
55
56    protected CompositeData getCompositeData() {
57        // CONTENTS OF THIS ARRAY MUST BE SYNCHRONIZED WITH
58        // monitorInfoItemNames!
59
60        int len = monitorInfoItemNames.length;
61        Object[] values = new Object[len];
62        CompositeData li = LockInfoCompositeData.toCompositeData(lock);
63
64        for (int i = 0; i < len; i++) {
65            String item = monitorInfoItemNames[i];
66            if (item.equals(LOCKED_STACK_FRAME)) {
67                StackTraceElement ste = lock.getLockedStackFrame();
68                values[i] = (ste != null ? StackTraceElementCompositeData.
69                                               toCompositeData(ste)
70                                         : null);
71            } else if (item.equals(LOCKED_STACK_DEPTH)) {
72                values[i] = lock.getLockedStackDepth();
73            } else {
74                values[i] = li.get(item);
75            }
76        }
77
78        try {
79            return new CompositeDataSupport(monitorInfoCompositeType,
80                                            monitorInfoItemNames,
81                                            values);
82        } catch (OpenDataException e) {
83            // Should never reach here
84            throw new AssertionError(e);
85        }
86    }
87
88    private static final CompositeType monitorInfoCompositeType;
89    private static final String[] monitorInfoItemNames;
90    static {
91        try {
92            monitorInfoCompositeType = (CompositeType)
93                MappedMXBeanType.toOpenType(MonitorInfo.class);
94            Set<String> s = monitorInfoCompositeType.keySet();
95            monitorInfoItemNames =  s.toArray(new String[0]);
96        } catch (OpenDataException e) {
97            // Should never reach here
98            throw new AssertionError(e);
99        }
100    }
101
102    static CompositeType getMonitorInfoCompositeType() {
103        return monitorInfoCompositeType;
104    }
105
106    private static final String CLASS_NAME         = "className";
107    private static final String IDENTITY_HASH_CODE = "identityHashCode";
108    private static final String LOCKED_STACK_FRAME = "lockedStackFrame";
109    private static final String LOCKED_STACK_DEPTH = "lockedStackDepth";
110
111    public static String getClassName(CompositeData cd) {
112        return getString(cd, CLASS_NAME);
113    }
114
115    public static int getIdentityHashCode(CompositeData cd) {
116        return getInt(cd, IDENTITY_HASH_CODE);
117    }
118
119    public static StackTraceElement getLockedStackFrame(CompositeData cd) {
120        CompositeData ste = (CompositeData) cd.get(LOCKED_STACK_FRAME);
121        if (ste != null) {
122            return StackTraceElementCompositeData.from(ste);
123        } else {
124            return null;
125        }
126    }
127
128    public static int getLockedStackDepth(CompositeData cd) {
129        return getInt(cd, LOCKED_STACK_DEPTH);
130    }
131
132    /** Validate if the input CompositeData has the expected
133     * CompositeType (i.e. contain all attributes with expected
134     * names and types).
135     */
136    public static void validateCompositeData(CompositeData cd) {
137        if (cd == null) {
138            throw new NullPointerException("Null CompositeData");
139        }
140
141        if (!isTypeMatched(monitorInfoCompositeType, cd.getCompositeType())) {
142            throw new IllegalArgumentException(
143                "Unexpected composite type for MonitorInfo");
144        }
145    }
146
147    private static final long serialVersionUID = -5825215591822908529L;
148}
149