Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
PojavLauncherTeam
GitHub Repository: PojavLauncherTeam/mobile
Path: blob/master/src/java.management/share/classes/com/sun/jmx/mbeanserver/PerInterface.java
41161 views
1
/*
2
* Copyright (c) 2005, 2021, 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 com.sun.jmx.mbeanserver;
27
28
import java.security.AccessController;
29
import java.util.Arrays;
30
import java.util.Collections;
31
import java.util.List;
32
import java.util.Map;
33
import javax.management.AttributeNotFoundException;
34
import javax.management.InvalidAttributeValueException;
35
import javax.management.MBeanException;
36
import javax.management.MBeanInfo;
37
import javax.management.ReflectionException;
38
39
import static com.sun.jmx.mbeanserver.Util.*;
40
41
/**
42
* Per-MBean-interface behavior. A single instance of this class can be shared
43
* by all MBeans of the same kind (Standard MBean or MXBean) that have the same
44
* MBean interface.
45
*
46
* @since 1.6
47
*/
48
final class PerInterface<M> {
49
PerInterface(Class<?> mbeanInterface, MBeanIntrospector<M> introspector,
50
MBeanAnalyzer<M> analyzer, MBeanInfo mbeanInfo) {
51
this.mbeanInterface = mbeanInterface;
52
this.introspector = introspector;
53
this.mbeanInfo = mbeanInfo;
54
analyzer.visit(new InitMaps());
55
}
56
57
Class<?> getMBeanInterface() {
58
return mbeanInterface;
59
}
60
61
MBeanInfo getMBeanInfo() {
62
return mbeanInfo;
63
}
64
65
boolean isMXBean() {
66
return introspector.isMXBean();
67
}
68
69
Object getAttribute(Object resource, String attribute, Object cookie)
70
throws AttributeNotFoundException,
71
MBeanException,
72
ReflectionException {
73
74
final M cm = getters.get(attribute);
75
if (cm == null) {
76
final String msg;
77
if (setters.containsKey(attribute))
78
msg = "Write-only attribute: " + attribute;
79
else
80
msg = "No such attribute: " + attribute;
81
throw new AttributeNotFoundException(msg);
82
}
83
return introspector.invokeM(cm, resource, (Object[]) null, cookie);
84
}
85
86
void setAttribute(Object resource, String attribute, Object value,
87
Object cookie)
88
throws AttributeNotFoundException,
89
InvalidAttributeValueException,
90
MBeanException,
91
ReflectionException {
92
93
final M cm = setters.get(attribute);
94
if (cm == null) {
95
final String msg;
96
if (getters.containsKey(attribute))
97
msg = "Read-only attribute: " + attribute;
98
else
99
msg = "No such attribute: " + attribute;
100
throw new AttributeNotFoundException(msg);
101
}
102
introspector.invokeSetter(attribute, cm, resource, value, cookie);
103
}
104
105
Object invoke(Object resource, String operation, Object[] params,
106
String[] signature, Object cookie)
107
throws MBeanException, ReflectionException {
108
109
final List<MethodAndSig> list = ops.get(operation);
110
if (list == null) {
111
final String msg = "No such operation: " + operation;
112
return noSuchMethod(msg, resource, operation, params, signature,
113
cookie);
114
}
115
if (signature == null)
116
signature = new String[0];
117
MethodAndSig found = null;
118
for (MethodAndSig mas : list) {
119
if (Arrays.equals(mas.signature, signature)) {
120
found = mas;
121
break;
122
}
123
}
124
if (found == null) {
125
final String badSig = sigString(signature);
126
final String msg;
127
if (list.size() == 1) { // helpful exception message
128
msg = "Signature mismatch for operation " + operation +
129
": " + badSig + " should be " +
130
sigString(list.get(0).signature);
131
} else {
132
msg = "Operation " + operation + " exists but not with " +
133
"this signature: " + badSig;
134
}
135
return noSuchMethod(msg, resource, operation, params, signature,
136
cookie);
137
}
138
return introspector.invokeM(found.method, resource, params, cookie);
139
}
140
141
/*
142
* This method is called when invoke doesn't find the named method.
143
* Before throwing an exception, we check to see whether the
144
* jmx.invoke.getters property is set, and if so whether the method
145
* being invoked might be a getter or a setter. If so we invoke it
146
* and return the result. This is for compatibility
147
* with code based on JMX RI 1.0 or 1.1 which allowed invoking getters
148
* and setters. It is *not* recommended that new code use this feature.
149
*
150
* Since this method is either going to throw an exception or use
151
* functionality that is strongly discouraged, we consider that its
152
* performance is not very important.
153
*
154
* A simpler way to implement the functionality would be to add the getters
155
* and setters to the operations map when jmx.invoke.getters is set.
156
* However, that means that the property is consulted when an MBean
157
* interface is being introspected and not thereafter. Previously,
158
* the property was consulted on every invocation. So this simpler
159
* implementation could potentially break code that sets and unsets
160
* the property at different times.
161
*/
162
@SuppressWarnings("removal")
163
private Object noSuchMethod(String msg, Object resource, String operation,
164
Object[] params, String[] signature,
165
Object cookie)
166
throws MBeanException, ReflectionException {
167
168
// Construct the exception that we will probably throw
169
final NoSuchMethodException nsme =
170
new NoSuchMethodException(operation + sigString(signature));
171
final ReflectionException exception =
172
new ReflectionException(nsme, msg);
173
174
if (introspector.isMXBean())
175
throw exception; // No compatibility requirement here
176
177
// Is the compatibility property set?
178
GetPropertyAction act = new GetPropertyAction("jmx.invoke.getters");
179
String invokeGettersS;
180
try {
181
invokeGettersS = AccessController.doPrivileged(act);
182
} catch (Exception e) {
183
// We don't expect an exception here but if we get one then
184
// we'll simply assume that the property is not set.
185
invokeGettersS = null;
186
}
187
if (invokeGettersS == null)
188
throw exception;
189
190
int rest = 0;
191
Map<String, M> methods = null;
192
if (signature == null || signature.length == 0) {
193
if (operation.startsWith("get"))
194
rest = 3;
195
else if (operation.startsWith("is"))
196
rest = 2;
197
if (rest != 0)
198
methods = getters;
199
} else if (signature.length == 1 &&
200
operation.startsWith("set")) {
201
rest = 3;
202
methods = setters;
203
}
204
205
if (rest != 0) {
206
String attrName = operation.substring(rest);
207
M method = methods.get(attrName);
208
if (method != null && introspector.getName(method).equals(operation)) {
209
String[] msig = introspector.getSignature(method);
210
if ((signature == null && msig.length == 0) ||
211
Arrays.equals(signature, msig)) {
212
return introspector.invokeM(method, resource, params, cookie);
213
}
214
}
215
}
216
217
throw exception;
218
}
219
220
private String sigString(String[] signature) {
221
StringBuilder b = new StringBuilder("(");
222
if (signature != null) {
223
for (String s : signature) {
224
if (b.length() > 1)
225
b.append(", ");
226
b.append(s);
227
}
228
}
229
return b.append(")").toString();
230
}
231
232
/**
233
* Visitor that sets up the method maps (operations, getters, setters).
234
*/
235
private class InitMaps implements MBeanAnalyzer.MBeanVisitor<M> {
236
public void visitAttribute(String attributeName,
237
M getter,
238
M setter) {
239
if (getter != null) {
240
introspector.checkMethod(getter);
241
final Object old = getters.put(attributeName, getter);
242
assert(old == null);
243
}
244
if (setter != null) {
245
introspector.checkMethod(setter);
246
final Object old = setters.put(attributeName, setter);
247
assert(old == null);
248
}
249
}
250
251
public void visitOperation(String operationName,
252
M operation) {
253
introspector.checkMethod(operation);
254
final String[] sig = introspector.getSignature(operation);
255
final MethodAndSig mas = new MethodAndSig();
256
mas.method = operation;
257
mas.signature = sig;
258
List<MethodAndSig> list = ops.get(operationName);
259
if (list == null)
260
list = Collections.singletonList(mas);
261
else {
262
if (list.size() == 1)
263
list = newList(list);
264
list.add(mas);
265
}
266
ops.put(operationName, list);
267
}
268
}
269
270
private class MethodAndSig {
271
M method;
272
String[] signature;
273
}
274
275
private final Class<?> mbeanInterface;
276
private final MBeanIntrospector<M> introspector;
277
private final MBeanInfo mbeanInfo;
278
private final Map<String, M> getters = newMap();
279
private final Map<String, M> setters = newMap();
280
private final Map<String, List<MethodAndSig>> ops = newMap();
281
}
282
283