blob: b67ac60d77c5fe4568682475b8746a80edabf773 [file] [log] [blame]
J. Duke319a3b92007-12-01 00:00:00 +00001/*
2 * Copyright 2000-2007 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
27package javax.management.openmbean;
28
29
30// java import
31//
32import java.util.Set;
33import javax.management.Descriptor;
34import javax.management.DescriptorRead; // for Javadoc
35import javax.management.ImmutableDescriptor;
36import javax.management.MBeanParameterInfo;
37
38// OpenMBeanAttributeInfoSupport and this class are very similar
39// but can't easily be refactored because there's no multiple inheritance.
40// The best we can do for refactoring is to put a bunch of static methods
41// in OpenMBeanAttributeInfoSupport and import them here.
42import static javax.management.openmbean.OpenMBeanAttributeInfoSupport.*;
43
44/**
45 * Describes a parameter used in one or more operations or
46 * constructors of an open MBean.
47 *
48 *
49 * @since 1.5
50 */
51public class OpenMBeanParameterInfoSupport
52 extends MBeanParameterInfo
53 implements OpenMBeanParameterInfo {
54
55 /* Serial version */
56 static final long serialVersionUID = -7235016873758443122L;
57
58 /**
59 * @serial The open mbean parameter's <i>open type</i>
60 */
61 private OpenType<?> openType;
62
63 /**
64 * @serial The open mbean parameter's default value
65 */
66 private Object defaultValue = null;
67
68 /**
69 * @serial The open mbean parameter's legal values. This {@link
70 * Set} is unmodifiable
71 */
72 private Set<?> legalValues = null; // to be constructed unmodifiable
73
74 /**
75 * @serial The open mbean parameter's min value
76 */
77 private Comparable minValue = null;
78
79 /**
80 * @serial The open mbean parameter's max value
81 */
82 private Comparable maxValue = null;
83
84
85 // As this instance is immutable, these two values need only
86 // be calculated once.
87 private transient Integer myHashCode = null; // As this instance is immutable, these two values
88 private transient String myToString = null; // need only be calculated once.
89
90
91 /**
92 * Constructs an {@code OpenMBeanParameterInfoSupport} instance,
93 * which describes the parameter used in one or more operations or
94 * constructors of a class of open MBeans, with the specified
95 * {@code name}, {@code openType} and {@code description}.
96 *
97 * @param name cannot be a null or empty string.
98 *
99 * @param description cannot be a null or empty string.
100 *
101 * @param openType cannot be null.
102 *
103 * @throws IllegalArgumentException if {@code name} or {@code
104 * description} are null or empty string, or {@code openType} is
105 * null.
106 */
107 public OpenMBeanParameterInfoSupport(String name,
108 String description,
109 OpenType<?> openType) {
110 this(name, description, openType, (Descriptor) null);
111 }
112
113 /**
114 * <p>Constructs an {@code OpenMBeanParameterInfoSupport} instance,
115 * which describes the parameter used in one or more operations or
116 * constructors of a class of open MBeans, with the specified
117 * {@code name}, {@code openType}, {@code description},
118 * and {@code descriptor}.</p>
119 *
120 * <p>The {@code descriptor} can contain entries that will define
121 * the values returned by certain methods of this class, as
122 * explained in the {@link <a href="package-summary.html#constraints">
123 * package description</a>}.
124 *
125 * @param name cannot be a null or empty string.
126 *
127 * @param description cannot be a null or empty string.
128 *
129 * @param openType cannot be null.
130 *
131 * @param descriptor The descriptor for the parameter. This may be null
132 * which is equivalent to an empty descriptor.
133 *
134 * @throws IllegalArgumentException if {@code name} or {@code
135 * description} are null or empty string, or {@code openType} is
136 * null, or the descriptor entries are invalid as described in the
137 * {@link <a href="package-summary.html#constraints">package
138 * description</a>}.
139 *
140 * @since 1.6
141 */
142 public OpenMBeanParameterInfoSupport(String name,
143 String description,
144 OpenType<?> openType,
145 Descriptor descriptor) {
146
147
148 // Construct parent's state
149 //
150 super(name,
151 (openType==null) ? null : openType.getClassName(),
152 description,
153 ImmutableDescriptor.union(descriptor,(openType==null)?null:
154 openType.getDescriptor()));
155
156 // Initialize this instance's specific state
157 //
158 this.openType = openType;
159
160 descriptor = getDescriptor(); // replace null by empty
161 this.defaultValue = valueFrom(descriptor, "defaultValue", openType);
162 this.legalValues = valuesFrom(descriptor, "legalValues", openType);
163 this.minValue = comparableValueFrom(descriptor, "minValue", openType);
164 this.maxValue = comparableValueFrom(descriptor, "maxValue", openType);
165
166 try {
167 check(this);
168 } catch (OpenDataException e) {
169 throw new IllegalArgumentException(e.getMessage(), e);
170 }
171 }
172
173
174 /**
175 * Constructs an {@code OpenMBeanParameterInfoSupport} instance,
176 * which describes the parameter used in one or more operations or
177 * constructors of a class of open MBeans, with the specified
178 * {@code name}, {@code openType}, {@code description} and {@code
179 * defaultValue}.
180 *
181 * @param name cannot be a null or empty string.
182 *
183 * @param description cannot be a null or empty string.
184 *
185 * @param openType cannot be null.
186 *
187 * @param defaultValue must be a valid value for the {@code
188 * openType} specified for this parameter; default value not
189 * supported for {@code ArrayType} and {@code TabularType}; can be
190 * null, in which case it means that no default value is set.
191 *
192 * @param <T> allows the compiler to check that the {@code defaultValue},
193 * if non-null, has the correct Java type for the given {@code openType}.
194 *
195 * @throws IllegalArgumentException if {@code name} or {@code
196 * description} are null or empty string, or {@code openType} is
197 * null.
198 *
199 * @throws OpenDataException if {@code defaultValue} is not a
200 * valid value for the specified {@code openType}, or {@code
201 * defaultValue} is non null and {@code openType} is an {@code
202 * ArrayType} or a {@code TabularType}.
203 */
204 public <T> OpenMBeanParameterInfoSupport(String name,
205 String description,
206 OpenType<T> openType,
207 T defaultValue)
208 throws OpenDataException {
209 this(name, description, openType, defaultValue, (T[]) null);
210 }
211
212 /**
213 * <p>Constructs an {@code OpenMBeanParameterInfoSupport} instance,
214 * which describes the parameter used in one or more operations or
215 * constructors of a class of open MBeans, with the specified
216 * {@code name}, {@code openType}, {@code description}, {@code
217 * defaultValue} and {@code legalValues}.</p>
218 *
219 * <p>The contents of {@code legalValues} are copied, so subsequent
220 * modifications of the array referenced by {@code legalValues}
221 * have no impact on this {@code OpenMBeanParameterInfoSupport}
222 * instance.</p>
223 *
224 * @param name cannot be a null or empty string.
225 *
226 * @param description cannot be a null or empty string.
227 *
228 * @param openType cannot be null.
229 *
230 * @param defaultValue must be a valid value for the {@code
231 * openType} specified for this parameter; default value not
232 * supported for {@code ArrayType} and {@code TabularType}; can be
233 * null, in which case it means that no default value is set.
234 *
235 * @param legalValues each contained value must be valid for the
236 * {@code openType} specified for this parameter; legal values not
237 * supported for {@code ArrayType} and {@code TabularType}; can be
238 * null or empty.
239 *
240 * @param <T> allows the compiler to check that the {@code
241 * defaultValue} and {@code legalValues}, if non-null, have the
242 * correct Java type for the given {@code openType}.
243 *
244 * @throws IllegalArgumentException if {@code name} or {@code
245 * description} are null or empty string, or {@code openType} is
246 * null.
247 *
248 * @throws OpenDataException if {@code defaultValue} is not a
249 * valid value for the specified {@code openType}, or one value in
250 * {@code legalValues} is not valid for the specified {@code
251 * openType}, or {@code defaultValue} is non null and {@code
252 * openType} is an {@code ArrayType} or a {@code TabularType}, or
253 * {@code legalValues} is non null and non empty and {@code
254 * openType} is an {@code ArrayType} or a {@code TabularType}, or
255 * {@code legalValues} is non null and non empty and {@code
256 * defaultValue} is not contained in {@code legalValues}.
257 */
258 public <T> OpenMBeanParameterInfoSupport(String name,
259 String description,
260 OpenType<T> openType,
261 T defaultValue,
262 T[] legalValues)
263 throws OpenDataException {
264 this(name, description, openType,
265 defaultValue, legalValues, null, null);
266 }
267
268
269 /**
270 * Constructs an {@code OpenMBeanParameterInfoSupport} instance,
271 * which describes the parameter used in one or more operations or
272 * constructors of a class of open MBeans, with the specified
273 * {@code name}, {@code openType}, {@code description}, {@code
274 * defaultValue}, {@code minValue} and {@code maxValue}.
275 *
276 * It is possible to specify minimal and maximal values only for
277 * an open type whose values are {@code Comparable}.
278 *
279 * @param name cannot be a null or empty string.
280 *
281 * @param description cannot be a null or empty string.
282 *
283 * @param openType cannot be null.
284 *
285 * @param defaultValue must be a valid value for the {@code
286 * openType} specified for this parameter; default value not
287 * supported for {@code ArrayType} and {@code TabularType}; can be
288 * null, in which case it means that no default value is set.
289 *
290 * @param minValue must be valid for the {@code openType}
291 * specified for this parameter; can be null, in which case it
292 * means that no minimal value is set.
293 *
294 * @param maxValue must be valid for the {@code openType}
295 * specified for this parameter; can be null, in which case it
296 * means that no maximal value is set.
297 *
298 * @param <T> allows the compiler to check that the {@code
299 * defaultValue}, {@code minValue}, and {@code maxValue}, if
300 * non-null, have the correct Java type for the given {@code
301 * openType}.
302 *
303 * @throws IllegalArgumentException if {@code name} or {@code
304 * description} are null or empty string, or {@code openType} is
305 * null.
306 *
307 * @throws OpenDataException if {@code defaultValue}, {@code
308 * minValue} or {@code maxValue} is not a valid value for the
309 * specified {@code openType}, or {@code defaultValue} is non null
310 * and {@code openType} is an {@code ArrayType} or a {@code
311 * TabularType}, or both {@code minValue} and {@code maxValue} are
312 * non-null and {@code minValue.compareTo(maxValue) > 0} is {@code
313 * true}, or both {@code defaultValue} and {@code minValue} are
314 * non-null and {@code minValue.compareTo(defaultValue) > 0} is
315 * {@code true}, or both {@code defaultValue} and {@code maxValue}
316 * are non-null and {@code defaultValue.compareTo(maxValue) > 0}
317 * is {@code true}.
318 */
319 public <T> OpenMBeanParameterInfoSupport(String name,
320 String description,
321 OpenType<T> openType,
322 T defaultValue,
323 Comparable<T> minValue,
324 Comparable<T> maxValue)
325 throws OpenDataException {
326 this(name, description, openType,
327 defaultValue, null, minValue, maxValue);
328 }
329
330 private <T> OpenMBeanParameterInfoSupport(String name,
331 String description,
332 OpenType<T> openType,
333 T defaultValue,
334 T[] legalValues,
335 Comparable<T> minValue,
336 Comparable<T> maxValue)
337 throws OpenDataException {
338 super(name,
339 (openType == null) ? null : openType.getClassName(),
340 description,
341 makeDescriptor(openType,
342 defaultValue, legalValues, minValue, maxValue));
343
344 this.openType = openType;
345
346 Descriptor d = getDescriptor();
347 this.defaultValue = defaultValue;
348 this.minValue = minValue;
349 this.maxValue = maxValue;
350 // We already converted the array into an unmodifiable Set
351 // in the descriptor.
352 this.legalValues = (Set<?>) d.getFieldValue("legalValues");
353
354 check(this);
355 }
356
357 /**
358 * An object serialized in a version of the API before Descriptors were
359 * added to this class will have an empty or null Descriptor.
360 * For consistency with our
361 * behavior in this version, we must replace the object with one
362 * where the Descriptors reflect the same values of openType, defaultValue,
363 * etc.
364 **/
365 private Object readResolve() {
366 if (getDescriptor().getFieldNames().length == 0) {
367 // This noise allows us to avoid "unchecked" warnings without
368 // having to suppress them explicitly.
369 OpenType<Object> xopenType = cast(openType);
370 Set<Object> xlegalValues = cast(legalValues);
371 Comparable<Object> xminValue = cast(minValue);
372 Comparable<Object> xmaxValue = cast(maxValue);
373 return new OpenMBeanParameterInfoSupport(
374 name, description, openType,
375 makeDescriptor(xopenType, defaultValue, xlegalValues,
376 xminValue, xmaxValue));
377 } else
378 return this;
379 }
380
381 /**
382 * Returns the open type for the values of the parameter described
383 * by this {@code OpenMBeanParameterInfoSupport} instance.
384 */
385 public OpenType<?> getOpenType() {
386 return openType;
387 }
388
389 /**
390 * Returns the default value for the parameter described by this
391 * {@code OpenMBeanParameterInfoSupport} instance, if specified,
392 * or {@code null} otherwise.
393 */
394 public Object getDefaultValue() {
395
396 // Special case for ArrayType and TabularType
397 // [JF] TODO: clone it so that it cannot be altered,
398 // [JF] TODO: if we decide to support defaultValue as an array itself.
399 // [JF] As of today (oct 2000) it is not supported so
400 // defaultValue is null for arrays. Nothing to do.
401
402 return defaultValue;
403 }
404
405 /**
406 * Returns an unmodifiable Set of legal values for the parameter
407 * described by this {@code OpenMBeanParameterInfoSupport}
408 * instance, if specified, or {@code null} otherwise.
409 */
410 public Set<?> getLegalValues() {
411
412 // Special case for ArrayType and TabularType
413 // [JF] TODO: clone values so that they cannot be altered,
414 // [JF] TODO: if we decide to support LegalValues as an array itself.
415 // [JF] As of today (oct 2000) it is not supported so
416 // legalValues is null for arrays. Nothing to do.
417
418 // Returns our legalValues Set (set was constructed unmodifiable)
419 return (legalValues);
420 }
421
422 /**
423 * Returns the minimal value for the parameter described by this
424 * {@code OpenMBeanParameterInfoSupport} instance, if specified,
425 * or {@code null} otherwise.
426 */
427 public Comparable<?> getMinValue() {
428
429 // Note: only comparable values have a minValue, so that's not
430 // the case of arrays and tabulars (always null).
431
432 return minValue;
433 }
434
435 /**
436 * Returns the maximal value for the parameter described by this
437 * {@code OpenMBeanParameterInfoSupport} instance, if specified,
438 * or {@code null} otherwise.
439 */
440 public Comparable<?> getMaxValue() {
441
442 // Note: only comparable values have a maxValue, so that's not
443 // the case of arrays and tabulars (always null).
444
445 return maxValue;
446 }
447
448 /**
449 * Returns {@code true} if this {@code
450 * OpenMBeanParameterInfoSupport} instance specifies a non-null
451 * default value for the described parameter, {@code false}
452 * otherwise.
453 */
454 public boolean hasDefaultValue() {
455
456 return (defaultValue != null);
457 }
458
459 /**
460 * Returns {@code true} if this {@code
461 * OpenMBeanParameterInfoSupport} instance specifies a non-null
462 * set of legal values for the described parameter, {@code false}
463 * otherwise.
464 */
465 public boolean hasLegalValues() {
466
467 return (legalValues != null);
468 }
469
470 /**
471 * Returns {@code true} if this {@code
472 * OpenMBeanParameterInfoSupport} instance specifies a non-null
473 * minimal value for the described parameter, {@code false}
474 * otherwise.
475 */
476 public boolean hasMinValue() {
477
478 return (minValue != null);
479 }
480
481 /**
482 * Returns {@code true} if this {@code
483 * OpenMBeanParameterInfoSupport} instance specifies a non-null
484 * maximal value for the described parameter, {@code false}
485 * otherwise.
486 */
487 public boolean hasMaxValue() {
488
489 return (maxValue != null);
490 }
491
492
493 /**
494 * Tests whether {@code obj} is a valid value for the parameter
495 * described by this {@code OpenMBeanParameterInfo} instance.
496 *
497 * @param obj the object to be tested.
498 *
499 * @return {@code true} if {@code obj} is a valid value
500 * for the parameter described by this
501 * {@code OpenMBeanParameterInfo} instance,
502 * {@code false} otherwise.
503 */
504 public boolean isValue(Object obj) {
505 return OpenMBeanAttributeInfoSupport.isValue(this, obj);
506 // compiler bug? should be able to omit class name here
507 // also below in toString and hashCode
508 }
509
510
511 /* *** Commodity methods from java.lang.Object *** */
512
513
514 /**
515 * <p>Compares the specified {@code obj} parameter with this {@code
516 * OpenMBeanParameterInfoSupport} instance for equality.</p>
517 *
518 * <p>Returns {@code true} if and only if all of the following
519 * statements are true:
520 *
521 * <ul>
522 * <li>{@code obj} is non null,</li>
523 * <li>{@code obj} also implements the {@code OpenMBeanParameterInfo}
524 * interface,</li>
525 * <li>their names are equal</li>
526 * <li>their open types are equal</li>
527 * <li>their default, min, max and legal values are equal.</li>
528 * </ul>
529 * This ensures that this {@code equals} method works properly for
530 * {@code obj} parameters which are different implementations of
531 * the {@code OpenMBeanParameterInfo} interface.
532 *
533 * <p>If {@code obj} also implements {@link DescriptorRead}, then its
534 * {@link DescriptorRead#getDescriptor() getDescriptor()} method must
535 * also return the same value as for this object.</p>
536 *
537 * @param obj the object to be compared for equality with this
538 * {@code OpenMBeanParameterInfoSupport} instance.
539 *
540 * @return {@code true} if the specified object is equal to this
541 * {@code OpenMBeanParameterInfoSupport} instance.
542 */
543 public boolean equals(Object obj) {
544 if (!(obj instanceof OpenMBeanParameterInfo))
545 return false;
546
547 OpenMBeanParameterInfo other = (OpenMBeanParameterInfo) obj;
548
549 return equal(this, other);
550 }
551
552 /**
553 * <p>Returns the hash code value for this {@code
554 * OpenMBeanParameterInfoSupport} instance.</p>
555 *
556 * <p>The hash code of an {@code OpenMBeanParameterInfoSupport}
557 * instance is the sum of the hash codes of all elements of
558 * information used in {@code equals} comparisons (ie: its name,
559 * its <i>open type</i>, its default, min, max and legal
560 * values, and its Descriptor).
561 *
562 * <p>This ensures that {@code t1.equals(t2)} implies that {@code
563 * t1.hashCode()==t2.hashCode()} for any two {@code
564 * OpenMBeanParameterInfoSupport} instances {@code t1} and {@code
565 * t2}, as required by the general contract of the method {@link
566 * Object#hashCode() Object.hashCode()}.
567 *
568 * <p>However, note that another instance of a class implementing
569 * the {@code OpenMBeanParameterInfo} interface may be equal to
570 * this {@code OpenMBeanParameterInfoSupport} instance as defined
571 * by {@link #equals(java.lang.Object)}, but may have a different
572 * hash code if it is calculated differently.
573 *
574 * <p>As {@code OpenMBeanParameterInfoSupport} instances are
575 * immutable, the hash code for this instance is calculated once,
576 * on the first call to {@code hashCode}, and then the same value
577 * is returned for subsequent calls.
578 *
579 * @return the hash code value for this {@code
580 * OpenMBeanParameterInfoSupport} instance
581 */
582 public int hashCode() {
583
584 // Calculate the hash code value if it has not yet been done
585 // (ie 1st call to hashCode())
586 //
587 if (myHashCode == null)
588 myHashCode = OpenMBeanAttributeInfoSupport.hashCode(this);
589
590 // return always the same hash code for this instance (immutable)
591 //
592 return myHashCode.intValue();
593 }
594
595 /**
596 * Returns a string representation of this
597 * {@code OpenMBeanParameterInfoSupport} instance.
598 * <p>
599 * The string representation consists of the name of this class (i.e.
600 * {@code javax.management.openmbean.OpenMBeanParameterInfoSupport}),
601 * the string representation of the name and open type of the described
602 * parameter, the string representation of its default, min, max and legal
603 * values and the string representation of its descriptor.
604 * <p>
605 * As {@code OpenMBeanParameterInfoSupport} instances are immutable,
606 * the string representation for this instance is calculated once,
607 * on the first call to {@code toString}, and then the same value
608 * is returned for subsequent calls.
609 *
610 * @return a string representation of this
611 * {@code OpenMBeanParameterInfoSupport} instance.
612 */
613 public String toString() {
614
615 // Calculate the string value if it has not yet been done (ie
616 // 1st call to toString())
617 //
618 if (myToString == null)
619 myToString = OpenMBeanAttributeInfoSupport.toString(this);
620
621 // return always the same string representation for this
622 // instance (immutable)
623 //
624 return myToString;
625 }
626
627}