001 /*
002 * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.management;
027
028 import com.sun.jmx.mbeanserver.Introspector;
029 import java.lang.annotation.Annotation;
030 import java.lang.reflect.Constructor;
031 import java.util.Arrays;
032
033 /**
034 * Describes a constructor exposed by an MBean. Instances of this
035 * class are immutable. Subclasses may be mutable but this is not
036 * recommended.
037 *
038 * @since 1.5
039 */
040 public class MBeanConstructorInfo extends MBeanFeatureInfo implements
041 Cloneable {
042
043 /* Serial version */
044 static final long serialVersionUID = 4433990064191844427L;
045
046 static final MBeanConstructorInfo[] NO_CONSTRUCTORS = new MBeanConstructorInfo[0];
047
048 /** @see MBeanInfo#arrayGettersSafe */
049 private final transient boolean arrayGettersSafe;
050
051 /**
052 * @serial The signature of the method, that is, the class names of the arguments.
053 */
054 private final MBeanParameterInfo[] signature;
055
056 /**
057 * Constructs an <CODE>MBeanConstructorInfo</CODE> object. The
058 * {@link Descriptor} of the constructed object will include
059 * fields contributed by any annotations on the {@code
060 * Constructor} object that contain the {@link DescriptorKey}
061 * meta-annotation.
062 *
063 * @param description A human readable description of the operation.
064 * @param constructor The <CODE>java.lang.reflect.Constructor</CODE>
065 * object describing the MBean constructor.
066 */
067 public MBeanConstructorInfo(String description,
068 Constructor constructor) {
069 this (constructor.getName(), description,
070 constructorSignature(constructor), Introspector
071 .descriptorForElement(constructor));
072 }
073
074 /**
075 * Constructs an <CODE>MBeanConstructorInfo</CODE> object.
076 *
077 * @param name The name of the constructor.
078 * @param signature <CODE>MBeanParameterInfo</CODE> objects
079 * describing the parameters(arguments) of the constructor. This
080 * may be null with the same effect as a zero-length array.
081 * @param description A human readable description of the constructor.
082 */
083 public MBeanConstructorInfo(String name, String description,
084 MBeanParameterInfo[] signature) {
085 this (name, description, signature, null);
086 }
087
088 /**
089 * Constructs an <CODE>MBeanConstructorInfo</CODE> object.
090 *
091 * @param name The name of the constructor.
092 * @param signature <CODE>MBeanParameterInfo</CODE> objects
093 * describing the parameters(arguments) of the constructor. This
094 * may be null with the same effect as a zero-length array.
095 * @param description A human readable description of the constructor.
096 * @param descriptor The descriptor for the constructor. This may be null
097 * which is equivalent to an empty descriptor.
098 *
099 * @since 1.6
100 */
101 public MBeanConstructorInfo(String name, String description,
102 MBeanParameterInfo[] signature, Descriptor descriptor) {
103 super (name, description, descriptor);
104
105 if (signature == null || signature.length == 0)
106 signature = MBeanParameterInfo.NO_PARAMS;
107 else
108 signature = signature.clone();
109 this .signature = signature;
110 this .arrayGettersSafe = MBeanInfo.arrayGettersSafe(this
111 .getClass(), MBeanConstructorInfo.class);
112 }
113
114 /**
115 * <p>Returns a shallow clone of this instance. The clone is
116 * obtained by simply calling <tt>super.clone()</tt>, thus calling
117 * the default native shallow cloning mechanism implemented by
118 * <tt>Object.clone()</tt>. No deeper cloning of any internal
119 * field is made.</p>
120 *
121 * <p>Since this class is immutable, cloning is chiefly of
122 * interest to subclasses.</p>
123 */
124 public Object clone() {
125 try {
126 return super .clone();
127 } catch (CloneNotSupportedException e) {
128 // should not happen as this class is cloneable
129 return null;
130 }
131 }
132
133 /**
134 * <p>Returns the list of parameters for this constructor. Each
135 * parameter is described by an <CODE>MBeanParameterInfo</CODE>
136 * object.</p>
137 *
138 * <p>The returned array is a shallow copy of the internal array,
139 * which means that it is a copy of the internal array of
140 * references to the <CODE>MBeanParameterInfo</CODE> objects but
141 * that each referenced <CODE>MBeanParameterInfo</CODE> object is
142 * not copied.</p>
143 *
144 * @return An array of <CODE>MBeanParameterInfo</CODE> objects.
145 */
146 public MBeanParameterInfo[] getSignature() {
147 if (signature.length == 0)
148 return signature;
149 else
150 return signature.clone();
151 }
152
153 private MBeanParameterInfo[] fastGetSignature() {
154 if (arrayGettersSafe)
155 return signature;
156 else
157 return getSignature();
158 }
159
160 public String toString() {
161 return getClass().getName() + "[" + "description="
162 + getDescription() + ", " + "name=" + getName() + ", "
163 + "signature=" + Arrays.asList(fastGetSignature())
164 + ", " + "descriptor=" + getDescriptor() + "]";
165 }
166
167 /**
168 * Compare this MBeanConstructorInfo to another.
169 *
170 * @param o the object to compare to.
171 *
172 * @return true if and only if <code>o</code> is an MBeanConstructorInfo such
173 * that its {@link #getName()}, {@link #getDescription()},
174 * {@link #getSignature()}, and {@link #getDescriptor()}
175 * values are equal (not necessarily
176 * identical) to those of this MBeanConstructorInfo. Two
177 * signature arrays are equal if their elements are pairwise
178 * equal.
179 */
180 public boolean equals(Object o) {
181 if (o == this )
182 return true;
183 if (!(o instanceof MBeanConstructorInfo))
184 return false;
185 MBeanConstructorInfo p = (MBeanConstructorInfo) o;
186 return (p.getName().equals(getName())
187 && p.getDescription().equals(getDescription())
188 && Arrays.equals(p.fastGetSignature(),
189 fastGetSignature()) && p.getDescriptor()
190 .equals(getDescriptor()));
191 }
192
193 /* Unlike attributes and operations, it's quite likely we'll have
194 more than one constructor with the same name and even
195 description, so we include the parameter array in the hashcode.
196 We don't include the description, though, because it could be
197 quite long and yet the same between constructors. Likewise for
198 the descriptor. */
199 public int hashCode() {
200 int hash = getName().hashCode();
201 MBeanParameterInfo[] sig = fastGetSignature();
202 for (int i = 0; i < sig.length; i++)
203 hash ^= sig[i].hashCode();
204 return hash;
205 }
206
207 private static MBeanParameterInfo[] constructorSignature(
208 Constructor cn) {
209 final Class[] classes = cn.getParameterTypes();
210 final Annotation[][] annots = cn.getParameterAnnotations();
211 return MBeanOperationInfo.parameters(classes, annots);
212 }
213 }
|