author | jfdenise |
Tue, 09 Dec 2008 15:36:14 +0100 | |
changeset 1699 | 3611e5fd6da5 |
parent 1510 | e747d3193ef2 |
child 1714 | 3eeb90939fe7 |
permissions | -rw-r--r-- |
2 | 1 |
/* |
2 |
* Copyright 1999-2006 Sun Microsystems, Inc. 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. Sun designates this |
|
8 |
* particular file as subject to the "Classpath" exception as provided |
|
9 |
* by Sun 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, |
|
22 |
* CA 95054 USA or visit www.sun.com if you need additional information or |
|
23 |
* have any questions. |
|
24 |
*/ |
|
25 |
||
26 |
package javax.management; |
|
27 |
||
28 |
import java.lang.reflect.Method; |
|
29 |
import java.security.AccessController; |
|
30 |
||
31 |
import com.sun.jmx.mbeanserver.GetPropertyAction; |
|
32 |
import com.sun.jmx.mbeanserver.Introspector; |
|
33 |
||
34 |
||
35 |
/** |
|
36 |
* Describes an MBean attribute exposed for management. Instances of |
|
37 |
* this class are immutable. Subclasses may be mutable but this is |
|
38 |
* not recommended. |
|
39 |
* |
|
40 |
* @since 1.5 |
|
41 |
*/ |
|
42 |
@SuppressWarnings("serial") // serialVersionUID not constant |
|
43 |
public class MBeanAttributeInfo extends MBeanFeatureInfo implements Cloneable { |
|
44 |
||
45 |
/* Serial version */ |
|
46 |
private static final long serialVersionUID; |
|
47 |
static { |
|
48 |
/* For complicated reasons, the serialVersionUID changed |
|
49 |
between JMX 1.0 and JMX 1.1, even though JMX 1.1 did not |
|
50 |
have compatibility code for this class. So the |
|
51 |
serialization produced by this class with JMX 1.2 and |
|
52 |
jmx.serial.form=1.0 is not the same as that produced by |
|
53 |
this class with JMX 1.1 and jmx.serial.form=1.0. However, |
|
54 |
the serialization without that property is the same, and |
|
55 |
that is the only form required by JMX 1.2. |
|
56 |
*/ |
|
57 |
long uid = 8644704819898565848L; |
|
58 |
try { |
|
59 |
GetPropertyAction act = new GetPropertyAction("jmx.serial.form"); |
|
60 |
String form = AccessController.doPrivileged(act); |
|
61 |
if ("1.0".equals(form)) |
|
62 |
uid = 7043855487133450673L; |
|
63 |
} catch (Exception e) { |
|
64 |
// OK: exception means no compat with 1.0, too bad |
|
65 |
} |
|
66 |
serialVersionUID = uid; |
|
67 |
} |
|
68 |
||
69 |
static final MBeanAttributeInfo[] NO_ATTRIBUTES = |
|
70 |
new MBeanAttributeInfo[0]; |
|
71 |
||
72 |
/** |
|
73 |
* @serial The actual attribute type. |
|
74 |
*/ |
|
75 |
private final String attributeType; |
|
76 |
||
77 |
/** |
|
78 |
* @serial The attribute write right. |
|
79 |
*/ |
|
80 |
private final boolean isWrite; |
|
81 |
||
82 |
/** |
|
83 |
* @serial The attribute read right. |
|
84 |
*/ |
|
85 |
private final boolean isRead; |
|
86 |
||
87 |
/** |
|
88 |
* @serial Indicates if this method is a "is" |
|
89 |
*/ |
|
90 |
private final boolean is; |
|
91 |
||
92 |
||
93 |
/** |
|
94 |
* Constructs an <CODE>MBeanAttributeInfo</CODE> object. |
|
95 |
* |
|
96 |
* @param name The name of the attribute. |
|
97 |
* @param type The type or class name of the attribute. |
|
98 |
* @param description A human readable description of the attribute. |
|
99 |
* @param isReadable True if the attribute has a getter method, false otherwise. |
|
100 |
* @param isWritable True if the attribute has a setter method, false otherwise. |
|
101 |
* @param isIs True if this attribute has an "is" getter, false otherwise. |
|
102 |
* |
|
103 |
* @throws IllegalArgumentException if {@code isIs} is true but |
|
104 |
* {@code isReadable} is not, or if {@code isIs} is true and |
|
105 |
* {@code type} is not {@code boolean} or {@code java.lang.Boolean}. |
|
106 |
* (New code should always use {@code boolean} rather than |
|
107 |
* {@code java.lang.Boolean}.) |
|
108 |
*/ |
|
109 |
public MBeanAttributeInfo(String name, |
|
110 |
String type, |
|
111 |
String description, |
|
112 |
boolean isReadable, |
|
113 |
boolean isWritable, |
|
114 |
boolean isIs) { |
|
115 |
this(name, type, description, isReadable, isWritable, isIs, |
|
116 |
(Descriptor) null); |
|
117 |
} |
|
118 |
||
119 |
/** |
|
120 |
* Constructs an <CODE>MBeanAttributeInfo</CODE> object. |
|
121 |
* |
|
122 |
* @param name The name of the attribute. |
|
123 |
* @param type The type or class name of the attribute. |
|
124 |
* @param description A human readable description of the attribute. |
|
125 |
* @param isReadable True if the attribute has a getter method, false otherwise. |
|
126 |
* @param isWritable True if the attribute has a setter method, false otherwise. |
|
127 |
* @param isIs True if this attribute has an "is" getter, false otherwise. |
|
128 |
* @param descriptor The descriptor for the attribute. This may be null |
|
129 |
* which is equivalent to an empty descriptor. |
|
130 |
* |
|
131 |
* @throws IllegalArgumentException if {@code isIs} is true but |
|
132 |
* {@code isReadable} is not, or if {@code isIs} is true and |
|
133 |
* {@code type} is not {@code boolean} or {@code java.lang.Boolean}. |
|
134 |
* (New code should always use {@code boolean} rather than |
|
135 |
* {@code java.lang.Boolean}.) |
|
136 |
* |
|
137 |
* @since 1.6 |
|
138 |
*/ |
|
139 |
public MBeanAttributeInfo(String name, |
|
140 |
String type, |
|
141 |
String description, |
|
142 |
boolean isReadable, |
|
143 |
boolean isWritable, |
|
144 |
boolean isIs, |
|
145 |
Descriptor descriptor) { |
|
146 |
super(name, description, descriptor); |
|
147 |
||
148 |
this.attributeType = type; |
|
149 |
this.isRead = isReadable; |
|
150 |
this.isWrite = isWritable; |
|
151 |
if (isIs && !isReadable) { |
|
152 |
throw new IllegalArgumentException("Cannot have an \"is\" getter " + |
|
153 |
"for a non-readable attribute"); |
|
154 |
} |
|
155 |
if (isIs && !type.equals("java.lang.Boolean") && |
|
156 |
!type.equals("boolean")) { |
|
157 |
throw new IllegalArgumentException("Cannot have an \"is\" getter " + |
|
158 |
"for a non-boolean attribute"); |
|
159 |
} |
|
160 |
this.is = isIs; |
|
161 |
} |
|
162 |
||
163 |
/** |
|
164 |
* <p>This constructor takes the name of a simple attribute, and Method |
|
165 |
* objects for reading and writing the attribute. The {@link Descriptor} |
|
166 |
* of the constructed object will include fields contributed by any |
|
167 |
* annotations on the {@code Method} objects that contain the |
|
168 |
* {@link DescriptorKey} meta-annotation. |
|
169 |
* |
|
170 |
* @param name The programmatic name of the attribute. |
|
171 |
* @param description A human readable description of the attribute. |
|
172 |
* @param getter The method used for reading the attribute value. |
|
173 |
* May be null if the property is write-only. |
|
174 |
* @param setter The method used for writing the attribute value. |
|
175 |
* May be null if the attribute is read-only. |
|
176 |
* @exception IntrospectionException There is a consistency |
|
177 |
* problem in the definition of this attribute. |
|
178 |
*/ |
|
179 |
public MBeanAttributeInfo(String name, |
|
180 |
String description, |
|
181 |
Method getter, |
|
182 |
Method setter) throws IntrospectionException { |
|
183 |
this(name, |
|
184 |
attributeType(getter, setter), |
|
185 |
description, |
|
186 |
(getter != null), |
|
187 |
(setter != null), |
|
188 |
isIs(getter), |
|
1699
3611e5fd6da5
6250014: MBeanOperationInfo Descriptor field for exceptions
jfdenise
parents:
1510
diff
changeset
|
189 |
ImmutableDescriptor.union(Introspector. |
3611e5fd6da5
6250014: MBeanOperationInfo Descriptor field for exceptions
jfdenise
parents:
1510
diff
changeset
|
190 |
descriptorForElement(getter, false), |
3611e5fd6da5
6250014: MBeanOperationInfo Descriptor field for exceptions
jfdenise
parents:
1510
diff
changeset
|
191 |
Introspector.descriptorForElement(setter, |
3611e5fd6da5
6250014: MBeanOperationInfo Descriptor field for exceptions
jfdenise
parents:
1510
diff
changeset
|
192 |
true))); |
2 | 193 |
} |
194 |
||
195 |
/** |
|
196 |
* <p>Returns a shallow clone of this instance. |
|
197 |
* The clone is obtained by simply calling <tt>super.clone()</tt>, |
|
198 |
* thus calling the default native shallow cloning mechanism |
|
199 |
* implemented by <tt>Object.clone()</tt>. |
|
200 |
* No deeper cloning of any internal field is made.</p> |
|
201 |
* |
|
202 |
* <p>Since this class is immutable, cloning is chiefly of |
|
203 |
* interest to subclasses.</p> |
|
204 |
*/ |
|
205 |
public Object clone () { |
|
206 |
try { |
|
207 |
return super.clone() ; |
|
208 |
} catch (CloneNotSupportedException e) { |
|
209 |
// should not happen as this class is cloneable |
|
210 |
return null; |
|
211 |
} |
|
212 |
} |
|
213 |
||
214 |
/** |
|
215 |
* Returns the class name of the attribute. |
|
216 |
* |
|
217 |
* @return the class name. |
|
218 |
*/ |
|
219 |
public String getType() { |
|
220 |
return attributeType; |
|
221 |
} |
|
222 |
||
223 |
/** |
|
224 |
* Whether the value of the attribute can be read. |
|
225 |
* |
|
226 |
* @return True if the attribute can be read, false otherwise. |
|
227 |
*/ |
|
228 |
public boolean isReadable() { |
|
229 |
return isRead; |
|
230 |
} |
|
231 |
||
232 |
/** |
|
233 |
* Whether new values can be written to the attribute. |
|
234 |
* |
|
235 |
* @return True if the attribute can be written to, false otherwise. |
|
236 |
*/ |
|
237 |
public boolean isWritable() { |
|
238 |
return isWrite; |
|
239 |
} |
|
240 |
||
241 |
/** |
|
242 |
* Indicates if this attribute has an "is" getter. |
|
243 |
* |
|
244 |
* @return true if this attribute has an "is" getter. |
|
245 |
*/ |
|
246 |
public boolean isIs() { |
|
247 |
return is; |
|
248 |
} |
|
249 |
||
250 |
public String toString() { |
|
251 |
String access; |
|
252 |
if (isReadable()) { |
|
253 |
if (isWritable()) |
|
254 |
access = "read/write"; |
|
255 |
else |
|
256 |
access = "read-only"; |
|
257 |
} else if (isWritable()) |
|
258 |
access = "write-only"; |
|
259 |
else |
|
260 |
access = "no-access"; |
|
261 |
||
262 |
return |
|
263 |
getClass().getName() + "[" + |
|
264 |
"description=" + getDescription() + ", " + |
|
265 |
"name=" + getName() + ", " + |
|
266 |
"type=" + getType() + ", " + |
|
267 |
access + ", " + |
|
268 |
(isIs() ? "isIs, " : "") + |
|
269 |
"descriptor=" + getDescriptor() + |
|
270 |
"]"; |
|
271 |
} |
|
272 |
||
273 |
/** |
|
274 |
* Compare this MBeanAttributeInfo to another. |
|
275 |
* |
|
276 |
* @param o the object to compare to. |
|
277 |
* |
|
278 |
* @return true if and only if <code>o</code> is an MBeanAttributeInfo such |
|
279 |
* that its {@link #getName()}, {@link #getType()}, {@link |
|
280 |
* #getDescription()}, {@link #isReadable()}, {@link |
|
281 |
* #isWritable()}, and {@link #isIs()} values are equal (not |
|
282 |
* necessarily identical) to those of this MBeanAttributeInfo. |
|
283 |
*/ |
|
284 |
public boolean equals(Object o) { |
|
285 |
if (o == this) |
|
286 |
return true; |
|
287 |
if (!(o instanceof MBeanAttributeInfo)) |
|
288 |
return false; |
|
289 |
MBeanAttributeInfo p = (MBeanAttributeInfo) o; |
|
290 |
return (p.getName().equals(getName()) && |
|
291 |
p.getType().equals(getType()) && |
|
292 |
p.getDescription().equals(getDescription()) && |
|
293 |
p.getDescriptor().equals(getDescriptor()) && |
|
294 |
p.isReadable() == isReadable() && |
|
295 |
p.isWritable() == isWritable() && |
|
296 |
p.isIs() == isIs()); |
|
297 |
} |
|
298 |
||
299 |
/* We do not include everything in the hashcode. We assume that |
|
300 |
if two operations are different they'll probably have different |
|
301 |
names or types. The penalty we pay when this assumption is |
|
302 |
wrong should be less than the penalty we would pay if it were |
|
303 |
right and we needlessly hashed in the description and parameter |
|
304 |
array. */ |
|
305 |
public int hashCode() { |
|
306 |
return getName().hashCode() ^ getType().hashCode(); |
|
307 |
} |
|
308 |
||
309 |
private static boolean isIs(Method getter) { |
|
310 |
return (getter != null && |
|
311 |
getter.getName().startsWith("is") && |
|
312 |
(getter.getReturnType().equals(Boolean.TYPE) || |
|
313 |
getter.getReturnType().equals(Boolean.class))); |
|
314 |
} |
|
315 |
||
316 |
/** |
|
317 |
* Finds the type of the attribute. |
|
318 |
*/ |
|
319 |
private static String attributeType(Method getter, Method setter) |
|
320 |
throws IntrospectionException { |
|
1510 | 321 |
Class<?> type = null; |
2 | 322 |
|
323 |
if (getter != null) { |
|
324 |
if (getter.getParameterTypes().length != 0) { |
|
325 |
throw new IntrospectionException("bad getter arg count"); |
|
326 |
} |
|
327 |
type = getter.getReturnType(); |
|
328 |
if (type == Void.TYPE) { |
|
329 |
throw new IntrospectionException("getter " + getter.getName() + |
|
330 |
" returns void"); |
|
331 |
} |
|
332 |
} |
|
333 |
||
334 |
if (setter != null) { |
|
1510 | 335 |
Class<?> params[] = setter.getParameterTypes(); |
2 | 336 |
if (params.length != 1) { |
337 |
throw new IntrospectionException("bad setter arg count"); |
|
338 |
} |
|
339 |
if (type == null) |
|
340 |
type = params[0]; |
|
341 |
else if (type != params[0]) { |
|
342 |
throw new IntrospectionException("type mismatch between " + |
|
343 |
"getter and setter"); |
|
344 |
} |
|
345 |
} |
|
346 |
||
347 |
if (type == null) { |
|
348 |
throw new IntrospectionException("getter and setter cannot " + |
|
349 |
"both be null"); |
|
350 |
} |
|
351 |
||
352 |
return type.getName(); |
|
353 |
} |
|
354 |
||
355 |
} |