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 }