View Javadoc
1   /*
2    * Copyright (c) 2000, 2008, Oracle and/or its affiliates. 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.  Oracle designates this
8    * particular file as subject to the "Classpath" exception as provided
9    * by Oracle 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 Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22   * or visit www.oracle.com if you need additional information or have any
23   * questions.
24   */
25  
26  
27  package javax.management.openmbean;
28  
29  
30  // java import
31  //
32  import java.util.Arrays;
33  
34  import javax.management.Descriptor;
35  import javax.management.MBeanConstructorInfo;
36  import javax.management.MBeanParameterInfo;
37  
38  
39  /**
40   * Describes a constructor of an Open MBean.
41   *
42   *
43   * @since 1.5
44   */
45  public class OpenMBeanConstructorInfoSupport
46      extends MBeanConstructorInfo
47      implements OpenMBeanConstructorInfo {
48  
49      /* Serial version */
50      static final long serialVersionUID = -4400441579007477003L;
51  
52  
53      // As this instance is immutable,
54      // these two values need only be calculated once.
55      private transient Integer myHashCode = null;
56      private transient String  myToString = null;
57  
58      /**
59       * <p>Constructs an {@code OpenMBeanConstructorInfoSupport}
60       * instance, which describes the constructor of a class of open
61       * MBeans with the specified {@code name}, {@code description} and
62       * {@code signature}.</p>
63       *
64       * <p>The {@code signature} array parameter is internally copied,
65       * so that subsequent changes to the array referenced by {@code
66       * signature} have no effect on this instance.</p>
67       *
68       * @param name cannot be a null or empty string.
69       *
70       * @param description cannot be a null or empty string.
71       *
72       * @param signature can be null or empty if there are no
73       * parameters to describe.
74       *
75       * @throws IllegalArgumentException if {@code name} or {@code
76       * description} are null or empty string.
77       *
78       * @throws ArrayStoreException If {@code signature} is not an
79       * array of instances of a subclass of {@code MBeanParameterInfo}.
80       */
81      public OpenMBeanConstructorInfoSupport(String name,
82                                             String description,
83                                             OpenMBeanParameterInfo[] signature) {
84          this(name, description, signature, (Descriptor) null);
85      }
86  
87      /**
88       * <p>Constructs an {@code OpenMBeanConstructorInfoSupport}
89       * instance, which describes the constructor of a class of open
90       * MBeans with the specified {@code name}, {@code description},
91       * {@code signature}, and {@code descriptor}.</p>
92       *
93       * <p>The {@code signature} array parameter is internally copied,
94       * so that subsequent changes to the array referenced by {@code
95       * signature} have no effect on this instance.</p>
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 signature can be null or empty if there are no
102      * parameters to describe.
103      *
104      * @param descriptor The descriptor for the constructor.  This may
105      * be null which is equivalent to an empty descriptor.
106      *
107      * @throws IllegalArgumentException if {@code name} or {@code
108      * description} are null or empty string.
109      *
110      * @throws ArrayStoreException If {@code signature} is not an
111      * array of instances of a subclass of {@code MBeanParameterInfo}.
112      *
113      * @since 1.6
114      */
115     public OpenMBeanConstructorInfoSupport(String name,
116                                            String description,
117                                            OpenMBeanParameterInfo[] signature,
118                                            Descriptor descriptor) {
119         super(name,
120               description,
121               arrayCopyCast(signature), // may throw an ArrayStoreException
122               descriptor);
123 
124         // check parameters that should not be null or empty
125         // (unfortunately it is not done in superclass :-( ! )
126         //
127         if (name == null || name.trim().equals("")) {
128             throw new IllegalArgumentException("Argument name cannot be " +
129                                                "null or empty");
130         }
131         if (description == null || description.trim().equals("")) {
132             throw new IllegalArgumentException("Argument description cannot " +
133                                                "be null or empty");
134         }
135 
136     }
137 
138     private static MBeanParameterInfo[]
139             arrayCopyCast(OpenMBeanParameterInfo[] src) {
140         if (src == null)
141             return null;
142 
143         MBeanParameterInfo[] dst = new MBeanParameterInfo[src.length];
144         System.arraycopy(src, 0, dst, 0, src.length);
145         // may throw an ArrayStoreException
146         return dst;
147     }
148 
149 
150     /* ***  Commodity methods from java.lang.Object  *** */
151 
152 
153     /**
154      * <p>Compares the specified {@code obj} parameter with this
155      * {@code OpenMBeanConstructorInfoSupport} instance for
156      * equality.</p>
157      *
158      * <p>Returns {@code true} if and only if all of the following
159      * statements are true:
160      *
161      * <ul>
162      * <li>{@code obj} is non null,</li>
163      * <li>{@code obj} also implements the {@code
164      * OpenMBeanConstructorInfo} interface,</li>
165      * <li>their names are equal</li>
166      * <li>their signatures are equal.</li>
167      * </ul>
168      *
169      * This ensures that this {@code equals} method works properly for
170      * {@code obj} parameters which are different implementations of
171      * the {@code OpenMBeanConstructorInfo} interface.
172      *
173      * @param obj the object to be compared for equality with this
174      * {@code OpenMBeanConstructorInfoSupport} instance;
175      *
176      * @return {@code true} if the specified object is equal to this
177      * {@code OpenMBeanConstructorInfoSupport} instance.
178      */
179     public boolean equals(Object obj) {
180 
181         // if obj is null, return false
182         //
183         if (obj == null) {
184             return false;
185         }
186 
187         // if obj is not a OpenMBeanConstructorInfo, return false
188         //
189         OpenMBeanConstructorInfo other;
190         try {
191             other = (OpenMBeanConstructorInfo) obj;
192         } catch (ClassCastException e) {
193             return false;
194         }
195 
196         // Now, really test for equality between this
197         // OpenMBeanConstructorInfo implementation and the other:
198         //
199 
200         // their Name should be equal
201         if ( ! this.getName().equals(other.getName()) ) {
202             return false;
203         }
204 
205         // their Signatures should be equal
206         if ( ! Arrays.equals(this.getSignature(), other.getSignature()) ) {
207             return false;
208         }
209 
210         // All tests for equality were successfull
211         //
212         return true;
213     }
214 
215     /**
216      * <p>Returns the hash code value for this {@code
217      * OpenMBeanConstructorInfoSupport} instance.</p>
218      *
219      * <p>The hash code of an {@code OpenMBeanConstructorInfoSupport}
220      * instance is the sum of the hash codes of all elements of
221      * information used in {@code equals} comparisons (ie: its name
222      * and signature, where the signature hashCode is calculated by a
223      * call to {@code
224      * java.util.Arrays.asList(this.getSignature).hashCode()}).</p>
225      *
226      * <p>This ensures that {@code t1.equals(t2)} implies that {@code
227      * t1.hashCode()==t2.hashCode()} for any two {@code
228      * OpenMBeanConstructorInfoSupport} instances {@code t1} and
229      * {@code t2}, as required by the general contract of the method
230      * {@link Object#hashCode() Object.hashCode()}.</p>
231      *
232      * <p>However, note that another instance of a class implementing
233      * the {@code OpenMBeanConstructorInfo} interface may be equal to
234      * this {@code OpenMBeanConstructorInfoSupport} instance as
235      * defined by {@link #equals(java.lang.Object)}, but may have a
236      * different hash code if it is calculated differently.</p>
237      *
238      * <p>As {@code OpenMBeanConstructorInfoSupport} instances are
239      * immutable, the hash code for this instance is calculated once,
240      * on the first call to {@code hashCode}, and then the same value
241      * is returned for subsequent calls.</p>
242      *
243      * @return the hash code value for this {@code
244      * OpenMBeanConstructorInfoSupport} instance
245      */
246     public int hashCode() {
247 
248         // Calculate the hash code value if it has not yet been done
249         // (ie 1st call to hashCode())
250         //
251         if (myHashCode == null) {
252             int value = 0;
253             value += this.getName().hashCode();
254             value += Arrays.asList(this.getSignature()).hashCode();
255             myHashCode = Integer.valueOf(value);
256         }
257 
258         // return always the same hash code for this instance (immutable)
259         //
260         return myHashCode.intValue();
261     }
262 
263     /**
264      * <p>Returns a string representation of this {@code
265      * OpenMBeanConstructorInfoSupport} instance.</p>
266      *
267      * <p>The string representation consists of the name of this class
268      * (ie {@code
269      * javax.management.openmbean.OpenMBeanConstructorInfoSupport}),
270      * the name and signature of the described constructor and the
271      * string representation of its descriptor.</p>
272      *
273      * <p>As {@code OpenMBeanConstructorInfoSupport} instances are
274      * immutable, the string representation for this instance is
275      * calculated once, on the first call to {@code toString}, and
276      * then the same value is returned for subsequent calls.</p>
277      *
278      * @return a string representation of this {@code
279      * OpenMBeanConstructorInfoSupport} instance
280      */
281     public String toString() {
282 
283         // Calculate the string value if it has not yet been done (ie
284         // 1st call to toString())
285         //
286         if (myToString == null) {
287             myToString = new StringBuilder()
288                 .append(this.getClass().getName())
289                 .append("(name=")
290                 .append(this.getName())
291                 .append(",signature=")
292                 .append(Arrays.asList(this.getSignature()).toString())
293                 .append(",descriptor=")
294                 .append(this.getDescriptor())
295                 .append(")")
296                 .toString();
297         }
298 
299         // return always the same string representation for this
300         // instance (immutable)
301         //
302         return myToString;
303     }
304 
305 }