001: /* JFox, the OpenSource J2EE Application Server
002: *
003: * Copyright (C) 2002 huihoo.org
004: * Distributable under GNU LGPL license
005: * See the GNU Lesser General Public License for more details.
006: */
007:
008: package javax.management.openmbean;
009:
010: import java.util.Set;
011: import java.util.Collections;
012: import java.util.HashSet;
013: import java.io.Serializable;
014: import javax.management.MBeanAttributeInfo;
015:
016: /**
017: * Describes an attribute of an open MBean.
018: *
019: * @author <a href="mailto:young_yy@hotmail.org">Young Yang</a>
020: */
021:
022: public class OpenMBeanAttributeInfoSupport extends MBeanAttributeInfo
023: implements OpenMBeanAttributeInfo, Serializable {
024:
025: /**
026: * @serial The open mbean attribute's <i>open type</i>
027: */
028: private OpenType openType;
029:
030: /**
031: * @serial The open mbean attribute's default value
032: */
033: private Object defaultValue = null;
034:
035: /**
036: * @serial The open mbean attribute's legal values. This {@link Set} is unmodifiable
037: */
038: private Set legalValues = null; // to be constructed unmodifiable
039:
040: /**
041: * @serial The open mbean attribute's min value
042: */
043: private Comparable minValue = null;
044:
045: /**
046: * @serial The open mbean attribute's max value
047: */
048: private Comparable maxValue = null;
049:
050: private transient Integer myHashCode = null; // As this instance is immutable, these two values
051: private transient String myToString = null; // need only be calculated once.
052:
053: /**
054: * Constructs an <tt>OpenMBeanAttributeInfoSupport</tt> instance, which describes the attribute of an open MBean
055: * with the specified <var>name</var>, <var>openType</var> and <var>description</var>,
056: * and the specified read/write access properties.
057: *
058: * @param name cannot be a null or empty string.
059: *
060: * @param description cannot be a null or empty string.
061: *
062: * @param openType cannot be null.
063: *
064: * @param isReadable <tt>true</tt> if the attribute has a getter exposed for management.
065: *
066: * @param isWritable <tt>true</tt> if the attribute has a setter exposed for management.
067: *
068: * @param isIs <tt>true</tt> if the attribute's getter is of the form <tt>is<i>XXX</i></tt>.
069: *
070: * @throws IllegalArgumentException if <var>name</var> or <var>description</var> are null or empty string,
071: * or <var>openType</var> is null.
072: */
073: public OpenMBeanAttributeInfoSupport(String name,
074: String description, OpenType openType, boolean isReadable,
075: boolean isWritable, boolean isIs) {
076:
077: // Construct parent's state
078: //
079: super (name, ((openType == null) ? null : openType
080: .getClassName()), description, isReadable, isWritable,
081: isIs);
082:
083: // check parameters that should not be null or empty (unfortunately it is not done in superclass :-( ! )
084: //
085: if ((name == null) || (name.trim().equals(""))) {
086: throw new IllegalArgumentException(
087: "Argument name cannot be null or empty.");
088: }
089: if (openType == null) {
090: throw new IllegalArgumentException(
091: "Argument openType cannot be null.");
092: }
093: if ((description == null) || (description.trim().equals(""))) {
094: throw new IllegalArgumentException(
095: "Argument description cannot be null or empty.");
096: }
097:
098: // Initialize this instance's specific state
099: //
100: this .openType = openType;
101: }
102:
103: /**
104: * Constructs an <tt>OpenMBeanAttributeInfoSupport</tt> instance, which describes the attribute of an open MBean
105: * with the specified <var>name</var>, <var>openType</var>, <var>description</var> and <var>defaultValue</var>,
106: * and the specified read/write access properties.
107: *
108: * @param name cannot be a null or empty string.
109: *
110: * @param description cannot be a null or empty string.
111: *
112: * @param openType cannot be null.
113: *
114: * @param isReadable <tt>true</tt> if the attribute has a getter exposed for management.
115: *
116: * @param isWritable <tt>true</tt> if the attribute has a setter exposed for management.
117: *
118: * @param isIs <tt>true</tt> if the attribute's getter is of the form <tt>is<i>XXX</i></tt>.
119: *
120: * @param defaultValue must be a valid value for the <var>openType</var> specified for this attribute;
121: * default value not supported for <tt>ArrayType</tt> and <tt>TabularType</tt>;
122: * can be null, in which case it means that no default value is set.
123: *
124: * @throws IllegalArgumentException if <var>name</var> or <var>description</var> are null or empty string,
125: * or <var>openType</var> is null.
126: *
127: * @throws OpenDataException if <var>defaultValue</var> is not a valid value for the specified <var>openType</var>,
128: * or <var>defaultValue</var> is non null and
129: * <var>openType</var> is an <tt>ArrayType</tt> or a <tt>TabularType</tt>.
130: */
131: public OpenMBeanAttributeInfoSupport(String name,
132: String description, OpenType openType, boolean isReadable,
133: boolean isWritable, boolean isIs, Object defaultValue)
134: throws OpenDataException {
135:
136: // First check and construct the part regarding name, openType and description
137: //
138: this (name, description, openType, isReadable, isWritable, isIs);
139:
140: // Check and initialize defaultValue
141: //
142: if (defaultValue != null) {
143: // Default value not supported for ArrayType and TabularType
144: if ((openType.isArray())
145: || (openType instanceof TabularType)) {
146: throw new OpenDataException(
147: "Default value not supported for ArrayType and TabularType.");
148: }
149: // Check defaultValue's class
150: if (!openType.isValue(defaultValue)) {
151: throw new OpenDataException(
152: "Argument defaultValue's class [\""
153: + defaultValue.getClass().getName()
154: + "\"] does not match the one defined in openType[\""
155: + openType.getClassName() + "\"].");
156: }
157: // Then initializes defaultValue:
158: // no need to clone it: apart from arrays and TabularData, basic data types are immutable
159: this .defaultValue = defaultValue;
160: }
161: }
162:
163: /**
164: * Constructs an <tt>OpenMBeanAttributeInfoSupport</tt> instance, which describes the attribute of an open MBean
165: * with the specified <var>name</var>, <var>openType</var>, <var>description</var>,
166: * <var>defaultValue</var> and <var>legalValues</var>,
167: * and the specified read/write access properties.
168: *
169: * The contents of <var>legalValues</var> are internally dumped into an unmodifiable <tt>Set</tt>,
170: * so subsequent modifications of the array referenced by <var>legalValues</var> have no impact on
171: * this <tt>OpenMBeanAttributeInfoSupport</tt> instance.
172: *
173: * @param name cannot be a null or empty string.
174: *
175: * @param description cannot be a null or empty string.
176: *
177: * @param openType cannot be null.
178: *
179: * @param isReadable <tt>true</tt> if the attribute has a getter exposed for management.
180: *
181: * @param isWritable <tt>true</tt> if the attribute has a setter exposed for management.
182: *
183: * @param isIs <tt>true</tt> if the attribute's getter is of the form <tt>is<i>XXX</i></tt>.
184: *
185: * @param defaultValue must be a valid value for the <var>openType</var> specified for this attribute;
186: * default value not supported for <tt>ArrayType</tt> and <tt>TabularType</tt>;
187: * can be null, in which case it means that no default value is set.
188: *
189: * @param legalValues each contained value must be valid for the <var>openType</var> specified for this attribute;
190: * legal values not supported for <tt>ArrayType</tt> and <tt>TabularType</tt>;
191: * can be null or empty.
192: *
193: * @throws IllegalArgumentException if <var>name</var> or <var>description</var> are null or empty string,
194: * or <var>openType</var> is null.
195: *
196: * @throws OpenDataException if <var>defaultValue</var> is not a valid value for the specified <var>openType</var>,
197: * or one value in <var>legalValues</var> is not valid for the specified <var>openType</var>,
198: * or <var>defaultValue</var> is non null and
199: * <var>openType</var> is an <tt>ArrayType</tt> or a <tt>TabularType</tt>,
200: * or <var>legalValues</var> is non null and non empty and
201: * <var>openType</var> is an <tt>ArrayType</tt> or a <tt>TabularType</tt>,
202: * or <var>legalValues</var> is non null and non empty and
203: * <var>defaultValue</var> is not contained in <var>legalValues</var>.
204: */
205: public OpenMBeanAttributeInfoSupport(String name,
206: String description, OpenType openType, boolean isReadable,
207: boolean isWritable, boolean isIs, Object defaultValue,
208: Object[] legalValues) throws OpenDataException {
209:
210: // First check and construct the part regarding name, openType, description and defaultValue
211: //
212: this (name, description, openType, isReadable, isWritable, isIs,
213: defaultValue);
214:
215: // Check and initialize legalValues
216: //
217: if ((legalValues != null) && (legalValues.length > 0)) {
218: // legalValues not supported for TabularType and arrays
219: if ((openType instanceof TabularType)
220: || (openType.isArray())) {
221: throw new OpenDataException(
222: "Legal values not supported for TabularType and arrays");
223: }
224: // Check legalValues are valid with openType
225: for (int i = 0; i < legalValues.length; i++) {
226: if (!openType.isValue(legalValues[i])) {
227: throw new OpenDataException(
228: "Element legalValues["
229: + i
230: + "]="
231: + legalValues[i]
232: + " is not a valid value for the specified openType ["
233: + openType.toString() + "].");
234: }
235: }
236: // dump the legalValues array content into a Set: ensures uniqueness of elements
237: // (and we could not keep the array reference as array content could be modified by the caller)
238: Set tmpSet = new HashSet(legalValues.length + 1, 1);
239: for (int i = 0; i < legalValues.length; i++) {
240: tmpSet.add(legalValues[i]);
241: }
242: // initializes legalValues as an unmodifiable Set
243: this .legalValues = Collections.unmodifiableSet(tmpSet);
244: }
245:
246: // Check that defaultValue is a legal value
247: //
248: if ((this .hasDefaultValue()) && (this .hasLegalValues())) {
249: if (!this .legalValues.contains(defaultValue)) {
250: throw new OpenDataException(
251: "defaultValue is not contained in legalValues");
252: }
253: }
254: }
255:
256: /**
257: * Constructs an <tt>OpenMBeanAttributeInfoSupport</tt> instance, which describes the attribute
258: * used in one or more operations or constructors of a class of open MBeans,
259: * with the specified <var>name</var>, <var>openType</var>, <var>description</var>,
260: * <var>defaultValue</var>, <var>minValue</var> and <var>maxValue</var>.
261: *
262: * It is possible to specify minimal and maximal values only for an open type
263: * whose values are <tt>Comparable</tt>.
264: *
265: * @param name cannot be a null or empty string.
266: *
267: * @param description cannot be a null or empty string.
268: *
269: * @param openType cannot be null.
270: *
271: * @param isReadable <tt>true</tt> if the attribute has a getter exposed for management.
272: *
273: * @param isWritable <tt>true</tt> if the attribute has a setter exposed for management.
274: *
275: * @param isIs <tt>true</tt> if the attribute's getter is of the form <tt>is<i>XXX</i></tt>.
276: *
277: * @param defaultValue must be a valid value for the <var>openType</var> specified for this attribute;
278: * default value not supported for <tt>ArrayType</tt> and <tt>TabularType</tt>;
279: * can be null, in which case it means that no default value is set.
280: *
281: * @param minValue must be valid for the <var>openType</var> specified for this attribute;
282: * can be null, in which case it means that no minimal value is set.
283: *
284: * @param maxValue must be valid for the <var>openType</var> specified for this attribute;
285: * can be null, in which case it means that no maximal value is set.
286: *
287: * @throws IllegalArgumentException if <var>name</var> or <var>description</var> are null or empty string,
288: * or <var>openType</var> is null.
289: *
290: * @throws OpenDataException if <var>defaultValue</var>, <var>minValue</var> or <var>maxValue</var>
291: * is not a valid value for the specified <var>openType</var>,
292: * or <var>defaultValue</var> is non null and
293: * <var>openType</var> is an <tt>ArrayType</tt> or a <tt>TabularType</tt>,
294: * or both <var>minValue</var> and <var>maxValue</var> are non-null and
295: * <tt>minValue.compareTo(maxValue) > 0</tt> is <tt>true</tt>,
296: * or both <var>defaultValue</var> and <var>minValue</var> are non-null and
297: * <tt>minValue.compareTo(defaultValue) > 0</tt> is <tt>true</tt>,
298: * or both <var>defaultValue</var> and <var>maxValue</var> are non-null and
299: * <tt>defaultValue.compareTo(maxValue) > 0</tt> is <tt>true</tt>.
300: */
301: public OpenMBeanAttributeInfoSupport(String name,
302: String description, OpenType openType, boolean isReadable,
303: boolean isWritable, boolean isIs, Object defaultValue,
304: Comparable minValue, Comparable maxValue)
305: throws OpenDataException {
306:
307: // First check and construct the part regarding name, openType, description and defaultValue
308: //
309: this (name, description, openType, isReadable, isWritable, isIs,
310: defaultValue);
311:
312: // Check and initialize minValue
313: //(note: no need to worry about Composite, Tabular and arrays as they are not Comparable)
314: //
315: if (minValue != null) {
316: if (!openType.isValue(minValue)) {
317: throw new OpenDataException(
318: "Argument minValue's class [\""
319: + minValue.getClass().getName()
320: + "\"] does not match openType's definition [\""
321: + openType.getClassName() + "\"].");
322: }
323: // then initializes minValue
324: this .minValue = minValue;
325: }
326:
327: // Check and initialize maxValue
328: //(note: no need to worry about Composite, Tabular and arrays as they are not Comparable)
329: //
330: if (maxValue != null) {
331: if (!openType.isValue(maxValue)) {
332: throw new OpenDataException(
333: "Argument maxValue's class [\""
334: + maxValue.getClass().getName()
335: + "\"] does not match openType's definition [\""
336: + openType.getClassName() + "\"].");
337: }
338: // then initializes maxValue
339: this .maxValue = maxValue;
340: }
341:
342: // Check that, if both specified, minValue <= maxValue
343: //
344: if (hasMinValue() && hasMaxValue()) {
345: if (minValue.compareTo(maxValue) > 0) {
346: throw new OpenDataException(
347: "minValue cannot be greater than maxValue.");
348: }
349: }
350:
351: // Check that minValue <= defaultValue <= maxValue
352: //
353: if ((this .hasDefaultValue()) && (this .hasMinValue())) {
354: if (minValue.compareTo(defaultValue) > 0) {
355: throw new OpenDataException(
356: "minValue cannot be greater than defaultValue.");
357: }
358: }
359: if ((this .hasDefaultValue()) && (this .hasMaxValue())) {
360: if (((Comparable) defaultValue).compareTo(maxValue) > 0) {
361: throw new OpenDataException(
362: "defaultValue cannot be greater than maxValue.");
363: }
364: }
365: }
366:
367: /**
368: * Returns the open type for the values of the attribute described by this <tt>OpenMBeanAttributeInfoSupport</tt> instance.
369: */
370: public OpenType getOpenType() {
371: return openType;
372: }
373:
374: /**
375: * Returns the default value for the attribute described by this <tt>OpenMBeanAttributeInfoSupport</tt> instance,
376: * if specified, or <tt>null</tt> otherwise.
377: */
378: public Object getDefaultValue() {
379:
380: // Special case for ArrayType and TabularType
381: // [JF] TODO: clone it so that it cannot be altered,
382: // [JF] TODO: if we decide to support defaultValue as an array itself.
383: // [JF] As of today (oct 2000) it is not supported so defaultValue is null for arrays. Nothing to do.
384:
385: return defaultValue;
386: }
387:
388: /**
389: * Returns an unmodifiable Set of legal values for the attribute described by this <tt>OpenMBeanAttributeInfoSupport</tt> instance,
390: * if specified, or <tt>null</tt> otherwise.
391: */
392: public Set getLegalValues() {
393:
394: // Special case for ArrayType and TabularType
395: // [JF] TODO: clone values so that they cannot be altered,
396: // [JF] TODO: if we decide to support LegalValues as an array itself.
397: // [JF] As of today (oct 2000) it is not supported so legalValues is null for arrays. Nothing to do.
398:
399: // Returns our legalValues Set (set was constructed unmodifiable)
400: return (legalValues);
401: }
402:
403: /**
404: * Returns the minimal value for the attribute described by this <tt>OpenMBeanAttributeInfoSupport</tt> instance,
405: * if specified, or <tt>null</tt> otherwise.
406: */
407: public Comparable getMinValue() {
408:
409: // Note: only comparable values have a minValue, so that's not the case of arrays and tabulars (always null).
410:
411: return minValue;
412: }
413:
414: /**
415: * Returns the maximal value for the attribute described by this <tt>OpenMBeanAttributeInfoSupport</tt> instance,
416: * if specified, or <tt>null</tt> otherwise.
417: */
418: public Comparable getMaxValue() {
419:
420: // Note: only comparable values have a maxValue, so that's not the case of arrays and tabulars (always null).
421:
422: return maxValue;
423: }
424:
425: /**
426: * Returns <tt>true</tt> if this <tt>OpenMBeanAttributeInfoSupport</tt> instance specifies a non-null default value
427: * for the described attribute, <tt>false</tt> otherwise.
428: */
429: public boolean hasDefaultValue() {
430:
431: return (defaultValue != null);
432: }
433:
434: /**
435: * Returns <tt>true</tt> if this <tt>OpenMBeanAttributeInfoSupport</tt> instance specifies a non-null set of legal values
436: * for the described attribute, <tt>false</tt> otherwise.
437: */
438: public boolean hasLegalValues() {
439:
440: return (legalValues != null);
441: }
442:
443: /**
444: * Returns <tt>true</tt> if this <tt>OpenMBeanAttributeInfoSupport</tt> instance specifies a non-null minimal value
445: * for the described attribute, <tt>false</tt> otherwise.
446: */
447: public boolean hasMinValue() {
448:
449: return (minValue != null);
450: }
451:
452: /**
453: * Returns <tt>true</tt> if this <tt>OpenMBeanAttributeInfoSupport</tt> instance specifies a non-null maximal value
454: * for the described attribute, <tt>false</tt> otherwise.
455: */
456: public boolean hasMaxValue() {
457:
458: return (maxValue != null);
459: }
460:
461: /**
462: * Tests whether <var>obj</var> is a valid value for the attribute
463: * described by this <code>OpenMBeanAttributeInfoSupport</code>
464: * instance.
465: *
466: * @param obj the object to be tested.
467: *
468: * @return <code>true</code> if <var>obj</var> is a valid value for for the parameter described by
469: * this <code>OpenMBeanAttributeInfoSupport</code> instance, <code>false</code> otherwise.
470: */
471: public boolean isValue(Object obj) {
472:
473: boolean result;
474:
475: if (hasDefaultValue() && obj == null) {
476: result = true;
477: } else if (!openType.isValue(obj)) {
478: result = false;
479: } else if (hasLegalValues() && !legalValues.contains(obj)) {
480: result = false;
481: } else if (hasMinValue() && (minValue.compareTo(obj) > 0)) {
482: result = false;
483: } else if (hasMaxValue() && (maxValue.compareTo(obj) < 0)) {
484: result = false;
485: } else {
486: result = true;
487: }
488:
489: return result;
490: }
491:
492: /* *** Commodity methods from java.lang.Object *** */
493:
494: /**
495: * Compares the specified <var>obj</var> parameter with this <code>OpenMBeanAttributeInfoSupport</code> instance for equality.
496: * <p>
497: * Returns <tt>true</tt> if and only if all of the following statements are true:
498: * <ul>
499: * <li><var>obj</var> is non null,</li>
500: * <li><var>obj</var> also implements the <code>OpenMBeanAttributeInfo</code> interface,</li>
501: * <li>their names are equal</li>
502: * <li>their open types are equal</li>
503: * <li>their access properties (isReadable, isWritable and isIs) are equal</li>
504: * <li>their default, min, max and legal values are equal.</li>
505: * </ul>
506: * This ensures that this <tt>equals</tt> method works properly for <var>obj</var> parameters which are
507: * different implementations of the <code>OpenMBeanAttributeInfo</code> interface.
508: * <br>
509: * @param obj the object to be compared for equality with this <code>OpenMBeanAttributeInfoSupport</code> instance;
510: *
511: * @return <code>true</code> if the specified object is equal to this <code>OpenMBeanAttributeInfoSupport</code> instance.
512: */
513: public boolean equals(Object obj) {
514:
515: // if obj is null, return false
516: //
517: if (obj == null) {
518: return false;
519: }
520:
521: // if obj is not a OpenMBeanAttributeInfo, return false
522: //
523: OpenMBeanAttributeInfo other;
524: try {
525: other = (OpenMBeanAttributeInfo) obj;
526: } catch (ClassCastException e) {
527: return false;
528: }
529:
530: // Now, really test for equality between this OpenMBeanAttributeInfo implementation and the other:
531: //
532:
533: // their Name should be equal
534: if (!this .getName().equals(other.getName())) {
535: return false;
536: }
537:
538: // their OpenType should be equal
539: if (!this .getOpenType().equals(other.getOpenType())) {
540: return false;
541: }
542:
543: // their access properties (isReadable, isWritable and isIs) are equal</li>
544: if ((this .isReadable() != other.isReadable())
545: || (this .isWritable() != other.isWritable())
546: || (this .isIs() != other.isIs())) {
547: return false;
548: }
549:
550: // their DefaultValue should be equal
551: if (this .hasDefaultValue()) {
552: if (!this .defaultValue.equals(other.getDefaultValue())) {
553: return false;
554: }
555: } else {
556: if (other.hasDefaultValue()) {
557: return false;
558: }
559: }
560:
561: // their MinValue should be equal
562: if (this .hasMinValue()) {
563: if (!this .minValue.equals(other.getMinValue())) {
564: return false;
565: }
566: } else {
567: if (other.hasMinValue()) {
568: return false;
569: }
570: }
571:
572: // their MaxValue should be equal
573: if (this .hasMaxValue()) {
574: if (!this .maxValue.equals(other.getMaxValue())) {
575: return false;
576: }
577: } else {
578: if (other.hasMaxValue()) {
579: return false;
580: }
581: }
582:
583: // their LegalValues should be equal
584: if (this .hasLegalValues()) {
585: if (!this .legalValues.equals(other.getLegalValues())) {
586: return false;
587: }
588: } else {
589: if (other.hasLegalValues()) {
590: return false;
591: }
592: }
593:
594: // All tests for equality were successfull
595: //
596: return true;
597: }
598:
599: /**
600: * Returns the hash code value for this <code>OpenMBeanAttributeInfoSupport</code> instance.
601: * <p>
602: * The hash code of an <code>OpenMBeanAttributeInfoSupport</code> instance is the sum of the hash codes
603: * of all elements of information used in <code>equals</code> comparisons
604: * (ie: its name, its <i>open type</i>, and its default, min, max and legal values).
605: * <p>
606: * This ensures that <code> t1.equals(t2) </code> implies that <code> t1.hashCode()==t2.hashCode() </code>
607: * for any two <code>OpenMBeanAttributeInfoSupport</code> instances <code>t1</code> and <code>t2</code>,
608: * as required by the general contract of the method
609: * {@link <a href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html#hashCode()">
610: * <code>Object.hashCode</code> </a>}.
611: * <p>
612: * However, note that another instance of a class implementing the <code>OpenMBeanAttributeInfo</code> interface
613: * may be equal to this <code>OpenMBeanAttributeInfoSupport</code> instance as defined by {@link #equals(java.lang.Object)},
614: * but may have a different hash code if it is calculated differently.
615: * <p>
616: * As <code>OpenMBeanAttributeInfoSupport</code> instances are immutable, the hash code for this instance is calculated once,
617: * on the first call to <code>hashCode</code>, and then the same value is returned for subsequent calls.
618: *
619: * @return the hash code value for this <code>OpenMBeanAttributeInfoSupport</code> instance
620: */
621: public int hashCode() {
622:
623: // Calculate the hash code value if it has not yet been done (ie 1st call to hashCode())
624: //
625: if (myHashCode == null) {
626: int value = 0;
627: value += this .getName().hashCode();
628: value += this .openType.hashCode();
629: if (this .hasDefaultValue()) {
630: value += this .defaultValue.hashCode();
631: }
632: if (this .hasMinValue()) {
633: value += this .minValue.hashCode();
634: }
635: if (this .hasMaxValue()) {
636: value += this .maxValue.hashCode();
637: }
638: if (this .hasLegalValues()) {
639: value += this .legalValues.hashCode();
640: }
641: myHashCode = new Integer(value);
642: }
643:
644: // return always the same hash code for this instance (immutable)
645: //
646: return myHashCode.intValue();
647: }
648:
649: /**
650: * Returns a string representation of this <code>OpenMBeanAttributeInfoSupport</code> instance.
651: * <p>
652: * The string representation consists of the name of this class (ie <code>javax.management.openmbean.OpenMBeanAttributeInfoSupport</code>),
653: * the string representation of the name and open type of the described parameter,
654: * and the string representation of its default, min, max and legal values.
655: * <p>
656: * As <code>OpenMBeanAttributeInfoSupport</code> instances are immutable, the string representation for this instance is calculated once,
657: * on the first call to <code>toString</code>, and then the same value is returned for subsequent calls.
658: *
659: * @return a string representation of this <code>OpenMBeanAttributeInfoSupport</code> instance
660: */
661: public String toString() {
662:
663: // Calculate the hash code value if it has not yet been done (ie 1st call to hashCode())
664: //
665: if (myToString == null) {
666: myToString = new StringBuffer().append(
667: this .getClass().getName()).append("(name=").append(
668: this .getName()).append(",openType=").append(
669: this .openType.toString()).append(",default=")
670: .append(String.valueOf(this .defaultValue)).append(
671: ",min=").append(
672: String.valueOf(this .minValue)).append(
673: ",max=").append(
674: String.valueOf(this .maxValue)).append(
675: ",legals=").append(
676: String.valueOf(this .legalValues)).append(
677: ")").toString();
678: }
679:
680: // return always the same string representation for this instance (immutable)
681: //
682: return myToString;
683: }
684:
685: }
|