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.io.Serializable;
011: import java.util.Arrays;
012: import javax.management.MBeanConstructorInfo;
013: import javax.management.MBeanParameterInfo;
014:
015: /**
016: * Describes a constructor of an Open MBean.
017: *
018: * @author <a href="mailto:young_yy@hotmail.org">Young Yang</a>
019: */
020:
021: public class OpenMBeanConstructorInfoSupport extends
022: MBeanConstructorInfo implements OpenMBeanConstructorInfo,
023: Serializable {
024:
025: private transient Integer myHashCode = null; // As this instance is immutable, these two values
026: private transient String myToString = null; // need only be calculated once.
027:
028: /**
029: * Constructs an <tt>OpenMBeanConstructorInfoSupport</tt> instance, which describes the constructor
030: * of a class of open MBeans with the specified <var>name</var>, <var>description</var> and <var>signature</var>.
031: * <p>
032: * The <var>signature</var> array parameter is internally copied, so that subsequent changes
033: * to the array referenced by <var>signature</var> have no effect on this instance.
034: *
035: * @param name cannot be a null or empty string.
036: *
037: * @param description cannot be a null or empty string.
038: *
039: * @param signature can be null or empty if there are no parameters to describe.
040: *
041: * @throws IllegalArgumentException if <var>name</var> or <var>description</var> are null or empty string.
042: *
043: * @throws ArrayStoreException If <var>signature</var> is not an array of instances of a subclass of <tt>MBeanParameterInfo</tt>.
044: */
045: public OpenMBeanConstructorInfoSupport(String name,
046: String description, OpenMBeanParameterInfo[] signature) {
047:
048: super (name, description, (signature == null ? null
049: : arrayCopyCast(signature))); // may throw an ArrayStoreException
050:
051: // check parameters that should not be null or empty (unfortunately it is not done in superclass :-( ! )
052: //
053: if ((name == null) || (name.trim().equals(""))) {
054: throw new IllegalArgumentException(
055: "Argument name cannot be null or empty.");
056: }
057: if ((description == null) || (description.trim().equals(""))) {
058: throw new IllegalArgumentException(
059: "Argument description cannot be null or empty.");
060: }
061:
062: }
063:
064: private static MBeanParameterInfo[] arrayCopyCast(
065: OpenMBeanParameterInfo[] src) throws ArrayStoreException {
066:
067: MBeanParameterInfo[] dst = new MBeanParameterInfo[src.length];
068: System.arraycopy(src, 0, dst, 0, src.length); // may throw an ArrayStoreException
069: return dst;
070: }
071:
072: /* *** Commodity methods from java.lang.Object *** */
073:
074: /**
075: * Compares the specified <var>obj</var> parameter with this <code>OpenMBeanConstructorInfoSupport</code> instance for equality.
076: * <p>
077: * Returns <tt>true</tt> if and only if all of the following statements are true:
078: * <ul>
079: * <li><var>obj</var> is non null,</li>
080: * <li><var>obj</var> also implements the <code>OpenMBeanConstructorInfo</code> interface,</li>
081: * <li>their names are equal</li>
082: * <li>their signatures are equal.</li>
083: * </ul>
084: * This ensures that this <tt>equals</tt> method works properly for <var>obj</var> parameters which are
085: * different implementations of the <code>OpenMBeanConstructorInfo</code> interface.
086: * <br>
087: * @param obj the object to be compared for equality with this <code>OpenMBeanConstructorInfoSupport</code> instance;
088: *
089: * @return <code>true</code> if the specified object is equal to this <code>OpenMBeanConstructorInfoSupport</code> instance.
090: */
091: public boolean equals(Object obj) {
092:
093: // if obj is null, return false
094: //
095: if (obj == null) {
096: return false;
097: }
098:
099: // if obj is not a OpenMBeanConstructorInfo, return false
100: //
101: OpenMBeanConstructorInfo other;
102: try {
103: other = (OpenMBeanConstructorInfo) obj;
104: } catch (ClassCastException e) {
105: return false;
106: }
107:
108: // Now, really test for equality between this OpenMBeanConstructorInfo implementation and the other:
109: //
110:
111: // their Name should be equal
112: if (!this .getName().equals(other.getName())) {
113: return false;
114: }
115:
116: // their Signatures should be equal
117: if (!Arrays.equals(this .getSignature(), other.getSignature())) {
118: return false;
119: }
120:
121: // All tests for equality were successfull
122: //
123: return true;
124: }
125:
126: /**
127: * Returns the hash code value for this <code>OpenMBeanConstructorInfoSupport</code> instance.
128: * <p>
129: * The hash code of an <code>OpenMBeanConstructorInfoSupport</code> instance is the sum of the hash codes
130: * of all elements of information used in <code>equals</code> comparisons
131: * (ie: its name and signature, where the signature hashCode is calculated by a call to
132: * <tt>java.util.Arrays.asList(this.getSignature).hashCode()</tt>).
133: * <p>
134: * This ensures that <code> t1.equals(t2) </code> implies that <code> t1.hashCode()==t2.hashCode() </code>
135: * for any two <code>OpenMBeanConstructorInfoSupport</code> instances <code>t1</code> and <code>t2</code>,
136: * as required by the general contract of the method
137: * {@link <a href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Object.html#hashCode()">
138: * <code>Object.hashCode</code> </a>}.
139: * <p>
140: * However, note that another instance of a class implementing the <code>OpenMBeanConstructorInfo</code> interface
141: * may be equal to this <code>OpenMBeanConstructorInfoSupport</code> instance as defined by {@link #equals(java.lang.Object)},
142: * but may have a different hash code if it is calculated differently.
143: * <p>
144: * As <code>OpenMBeanConstructorInfoSupport</code> instances are immutable, the hash code for this instance is calculated once,
145: * on the first call to <code>hashCode</code>, and then the same value is returned for subsequent calls.
146: *
147: * @return the hash code value for this <code>OpenMBeanConstructorInfoSupport</code> instance
148: */
149: public int hashCode() {
150:
151: // Calculate the hash code value if it has not yet been done (ie 1st call to hashCode())
152: //
153: if (myHashCode == null) {
154: int value = 0;
155: value += this .getName().hashCode();
156: value += Arrays.asList(this .getSignature()).hashCode();
157: myHashCode = new Integer(value);
158: }
159:
160: // return always the same hash code for this instance (immutable)
161: //
162: return myHashCode.intValue();
163: }
164:
165: /**
166: * Returns a string representation of this <code>OpenMBeanConstructorInfoSupport</code> instance.
167: * <p>
168: * The string representation consists of the name of this class (ie <code>javax.management.openmbean.OpenMBeanConstructorInfoSupport</code>),
169: * and of the name and signature of the described constructor.
170: * <p>
171: * As <code>OpenMBeanConstructorInfoSupport</code> instances are immutable,
172: * the string representation for this instance is calculated once,
173: * on the first call to <code>toString</code>, and then the same value is returned for subsequent calls.
174: *
175: * @return a string representation of this <code>OpenMBeanConstructorInfoSupport</code> instance
176: */
177: public String toString() {
178:
179: // Calculate the hash code value if it has not yet been done (ie 1st call to toString())
180: //
181: if (myToString == null) {
182: myToString = new StringBuffer().append(
183: this .getClass().getName()).append("(name=").append(
184: this .getName()).append(",signature=").append(
185: Arrays.asList(this .getSignature()).toString())
186: .append(")").toString();
187: }
188:
189: // return always the same string representation for this instance (immutable)
190: //
191: return myToString;
192: }
193:
194: }
|