KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > javax > management > openmbean > CompositeType


1 /*
2  * @(#)CompositeType.java 3.25 03/12/19
3  *
4  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
5  * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
6  */

7
8
9 package javax.management.openmbean;
10
11
12 // java import
13
//
14
import java.io.Serializable JavaDoc;
15 import java.util.Set JavaDoc;
16 import java.util.TreeMap JavaDoc;
17 import java.util.Collections JavaDoc;
18 import java.util.Iterator JavaDoc;
19
20 // jmx import
21
//
22

23
24 /**
25  * The <code>CompositeType</code> class is the <i>open type</i> class
26  * whose instances describe the types of {@link CompositeData <code>CompositeData</code>} values.
27  *
28  * @version 3.25 03/12/19
29  * @author Sun Microsystems, Inc.
30  *
31  * @since 1.5
32  * @since.unbundled JMX 1.1
33  */

34 public class CompositeType
35     extends OpenType JavaDoc
36     implements Serializable JavaDoc {
37
38     /* Serial version */
39     static final long serialVersionUID = -5366242454346948798L;
40
41     /**
42      * @serial Sorted mapping of the item names to their descriptions
43      */

44     private TreeMap JavaDoc nameToDescription;
45     
46     /**
47      * @serial Sorted mapping of the item names to their open types
48      */

49     private TreeMap JavaDoc nameToType;
50
51     private transient Integer JavaDoc myHashCode = null; // As this instance is immutable,
52
private transient String JavaDoc myToString = null; // these three values
53
private transient Set JavaDoc myNamesSet = null; // need only be calculated once.
54

55
56     /* *** Constructor *** */
57
58     /**
59      * Constructs a <code>CompositeType</code> instance, checking for the validity of the given parameters.
60      * The validity constraints are described below for each parameter.
61      * <p>
62      * Note that the contents of the three array parameters
63      * <var>itemNames</var>, <var>itemDescriptions</var> and <var>itemTypes</var>
64      * are internally copied so that any subsequent modification of these arrays by the caller of this constructor
65      * has no impact on the constructed <code>CompositeType</code> instance.
66      * <p>
67      * The Java class name of composite data values this composite type represents
68      * (ie the class name returned by the {@link OpenType#getClassName() getClassName} method)
69      * is set to the string value returned by <code>CompositeData.class.getName()</code>.
70      * <p>
71      * @param typeName The name given to the composite type this instance represents; cannot be a null or empty string.
72      * <br>&nbsp;
73      * @param description The human readable description of the composite type this instance represents;
74      * cannot be a null or empty string.
75      * <br>&nbsp;
76      * @param itemNames The names of the items contained in the
77      * composite data values described by this <code>CompositeType</code> instance;
78      * cannot be null and should contain at least one element; no element can be a null or empty string.
79      * Note that the order in which the item names are given is not important to differentiate a
80      * <code>CompositeType</code> instance from another;
81      * the item names are internally stored sorted in ascending alphanumeric order.
82      * <br>&nbsp;
83      * @param itemDescriptions The descriptions, in the same order as <var>itemNames</var>, of the items contained in the
84      * composite data values described by this <code>CompositeType</code> instance;
85      * should be of the same size as <var>itemNames</var>;
86      * no element can be a null or empty string.
87      * <br>&nbsp;
88      * @param itemTypes The open type instances, in the same order as <var>itemNames</var>, describing the items contained
89      * in the composite data values described by this <code>CompositeType</code> instance;
90      * should be of the same size as <var>itemNames</var>;
91      * no element can be null.
92      * <br>&nbsp;
93      * @throws IllegalArgumentException If <var>typeName</var> or <var>description</var> is a null or empty string,
94      * or <var>itemNames</var> or <var>itemDescriptions</var> or <var>itemTypes</var> is null,
95      * or any element of <var>itemNames</var> or <var>itemDescriptions</var>
96      * is a null or empty string,
97      * or any element of <var>itemTypes</var> is null,
98      * or <var>itemNames</var> or <var>itemDescriptions</var> or <var>itemTypes</var>
99      * are not of the same size.
100      * <br>&nbsp;
101      * @throws OpenDataException If <var>itemNames</var> contains duplicate item names
102      * (case sensitive, but leading and trailing whitespaces removed).
103      */

104     public CompositeType(String JavaDoc typeName,
105              String JavaDoc description,
106              String JavaDoc[] itemNames,
107              String JavaDoc[] itemDescriptions,
108              OpenType JavaDoc[] itemTypes) throws OpenDataException JavaDoc {
109
110     // Check and construct state defined by parent
111
//
112
super(CompositeData JavaDoc.class.getName(), typeName, description);
113
114     // Check the 3 arrays are not null or empty (ie length==0) and that there is no null element or empty string in them
115
//
116
checkForNullElement(itemNames, "itemNames");
117     checkForNullElement(itemDescriptions, "itemDescriptions");
118     checkForNullElement(itemTypes, "itemTypes");
119     checkForEmptyString(itemNames, "itemNames");
120     checkForEmptyString(itemDescriptions, "itemDescriptions");
121
122     // Check the sizes of the 3 arrays are the same
123
//
124
if ( (itemNames.length != itemDescriptions.length) || (itemNames.length != itemTypes.length) ) {
125         throw new IllegalArgumentException JavaDoc("Array arguments itemNames[], itemDescriptions[] and itemTypes[] "+
126                            "should be of same length (got "+ itemNames.length +", "+
127                            itemDescriptions.length +" and "+ itemTypes.length +").");
128     }
129     
130     // Initialize internal "names to descriptions" and "names to types" sorted maps,
131
// and, by doing so, check there are no duplicate item names
132
//
133
nameToDescription = new TreeMap JavaDoc();
134     nameToType = new TreeMap JavaDoc();
135     String JavaDoc key;
136     for (int i=0; i<itemNames.length; i++) {
137         key = itemNames[i].trim();
138         if (nameToDescription.containsKey(key)) {
139         throw new OpenDataException JavaDoc("Argument's element itemNames["+ i +"]=\""+ itemNames[i] +
140                         "\" duplicates a previous item names.");
141         }
142         nameToDescription.put(key, itemDescriptions[i].trim());
143         nameToType.put(key, itemTypes[i]);
144     }
145     }
146
147     private static void checkForNullElement(Object JavaDoc[] arg, String JavaDoc argName) {
148     if ( (arg == null) || (arg.length == 0) ) {
149         throw new IllegalArgumentException JavaDoc("Argument "+ argName +"[] cannot be null or empty.");
150     }
151     for (int i=0; i<arg.length; i++) {
152         if (arg[i] == null) {
153         throw new IllegalArgumentException JavaDoc("Argument's element "+ argName +"["+ i +"] cannot be null.");
154         }
155     }
156     }
157
158     private static void checkForEmptyString(String JavaDoc[] arg, String JavaDoc argName) {
159     for (int i=0; i<arg.length; i++) {
160         if (arg[i].trim().equals("")) {
161         throw new IllegalArgumentException JavaDoc("Argument's element "+ argName +"["+ i +"] cannot be an empty string.");
162         }
163     }
164     }
165
166     /* *** Composite type specific information methods *** */
167
168     /**
169      * Returns <code>true</code> if this <code>CompositeType</code> instance defines an item
170      * whose name is <var>itemName</var>.
171      *
172      * @param itemName the name of the item.
173      *
174      * @return true if an item of this name is present.
175      */

176     public boolean containsKey(String JavaDoc itemName) {
177
178     if (itemName == null) {
179         return false;
180     }
181     return nameToDescription.containsKey(itemName);
182     }
183
184     /**
185      * Returns the description of the item whose name is <var>itemName</var>,
186      * or <code>null</code> if this <code>CompositeType</code> instance does not define any item
187      * whose name is <var>itemName</var>.
188      *
189      * @param itemName the name of the item.
190      *
191      * @return the description.
192      */

193     public String JavaDoc getDescription(String JavaDoc itemName) {
194
195     if (itemName == null) {
196         return null;
197     }
198     return (String JavaDoc) nameToDescription.get(itemName);
199     }
200
201     /**
202      * Returns the <i>open type</i> of the item whose name is <var>itemName</var>,
203      * or <code>null</code> if this <code>CompositeType</code> instance does not define any item
204      * whose name is <var>itemName</var>.
205      *
206      * @param itemName the name of the time.
207      *
208      * @return the type.
209      */

210     public OpenType JavaDoc getType(String JavaDoc itemName) {
211
212     if (itemName == null) {
213         return null;
214     }
215     return (OpenType JavaDoc) nameToType.get(itemName);
216     }
217
218     /**
219      * Returns an unmodifiable Set view of all the item names defined by this <code>CompositeType</code> instance.
220      * The set's iterator will return the item names in ascending order.
221      *
222      * @return a {@link Set} of {@link String}.
223      */

224     public Set JavaDoc keySet() {
225
226     // Initializes myNamesSet on first call
227
if (myNamesSet == null) {
228         myNamesSet = Collections.unmodifiableSet(nameToDescription.keySet());
229     }
230
231     return myNamesSet; // always return the same value
232
}
233
234
235     /**
236      * Tests whether <var>obj</var> is a value which could be described by this <code>CompositeType</code> instance.
237      * <p>
238      * If <var>obj</var> is null or is not an instance of <code>javax.management.openmbean.CompositeData</code>,
239      * <code>isValue</code> returns <code>false</code>.
240      * If <var>obj</var> is an instance of <code>javax.management.openmbean.CompositeData</code>,
241      * its composite type is tested for equality with this <code>CompositeType</code> instance, and <code>isValue</code>
242      * returns <code>true</code> if and only if {@link #equals(java.lang.Object) <code>equals</code>}
243      * returns <code>true</code>.
244      * <br>&nbsp;
245      * @param obj the value whose open type is to be tested for equality with this <code>CompositeType</code> instance.
246      *
247      * @return <code>true</code> if <var>obj</var> is a value for this composite type, <code>false</code> otherwise.
248      */

249     public boolean isValue(Object JavaDoc obj) {
250
251     // if obj is null, return false
252
//
253
if (obj == null) {
254         return false;
255     }
256
257     // if obj is not a CompositeData, return false
258
//
259
CompositeData JavaDoc value;
260     try {
261         value = (CompositeData JavaDoc) obj;
262     } catch (ClassCastException JavaDoc e) {
263         return false;
264     }
265
266     // test value's CompositeType for equality with this CompositeType instance
267
//
268
return this.equals(value.getCompositeType());
269     }
270
271
272     /* *** Methods overriden from class Object *** */
273
274     /**
275      * Compares the specified <code>obj</code> parameter with this <code>CompositeType</code> instance for equality.
276      * <p>
277      * Two <code>CompositeType</code> instances are equal if and only if all of the following statements are true:
278      * <ul>
279      * <li>their type names are equal</li>
280      * <li>their items' names and types are equal</li>
281      * </ul>
282      * <br>&nbsp;
283      * @param obj the object to be compared for equality with this <code>CompositeType</code> instance;
284      * if <var>obj</var> is <code>null</code>, <code>equals</code> returns <code>false</code>.
285      *
286      * @return <code>true</code> if the specified object is equal to this <code>CompositeType</code> instance.
287      */

288     public boolean equals(Object JavaDoc obj) {
289
290     // if obj is null, return false
291
//
292
if (obj == null) {
293         return false;
294     }
295
296     // if obj is not a CompositeType, return false
297
//
298
CompositeType JavaDoc other;
299     try {
300         other = (CompositeType JavaDoc) obj;
301     } catch (ClassCastException JavaDoc e) {
302         return false;
303     }
304
305     // Now, really test for equality between this CompositeType instance and the other
306
//
307

308     // their names should be equal
309
if ( ! this.getTypeName().equals(other.getTypeName()) ) {
310         return false;
311     }
312
313     // their items names and types should be equal
314
if ( ! this.nameToType.equals(other.nameToType) ) {
315         return false;
316     }
317
318     // All tests for equality were successfull
319
//
320
return true;
321     }
322
323     /**
324      * Returns the hash code value for this <code>CompositeType</code> instance.
325      * <p>
326      * The hash code of a <code>CompositeType</code> instance is the sum of the hash codes
327      * of all elements of information used in <code>equals</code> comparisons
328      * (ie: name, items names, items types).
329      * This ensures that <code> t1.equals(t2) </code> implies that <code> t1.hashCode()==t2.hashCode() </code>
330      * for any two <code>CompositeType</code> instances <code>t1</code> and <code>t2</code>,
331      * as required by the general contract of the method
332      * {@link Object#hashCode() Object.hashCode()}.
333      * <p>
334      * As <code>CompositeType</code> instances are immutable, the hash code for this instance is calculated once,
335      * on the first call to <code>hashCode</code>, and then the same value is returned for subsequent calls.
336      *
337      * @return the hash code value for this <code>CompositeType</code> instance
338      */

339     public int hashCode() {
340
341     // Calculate the hash code value if it has not yet been done (ie 1st call to hashCode())
342
//
343
if (myHashCode == null) {
344         int value = 0;
345         value += this.getTypeName().hashCode();
346         String JavaDoc key;
347         for (Iterator JavaDoc k = nameToDescription.keySet().iterator(); k.hasNext(); ) {
348         key = (String JavaDoc) k.next();
349         value += key.hashCode();
350         value += this.nameToType.get(key).hashCode();
351         }
352         myHashCode = new Integer JavaDoc(value);
353     }
354     
355     // return always the same hash code for this instance (immutable)
356
//
357
return myHashCode.intValue();
358     }
359
360     /**
361      * Returns a string representation of this <code>CompositeType</code> instance.
362      * <p>
363      * The string representation consists of
364      * the name of this class (ie <code>javax.management.openmbean.CompositeType</code>), the type name for this instance,
365      * and the list of the items names and types string representation of this instance.
366      * <p>
367      * As <code>CompositeType</code> instances are immutable, the string representation for this instance is calculated once,
368      * on the first call to <code>toString</code>, and then the same value is returned for subsequent calls.
369      *
370      * @return a string representation of this <code>CompositeType</code> instance
371      */

372     public String JavaDoc toString() {
373
374     // Calculate the string representation if it has not yet been done (ie 1st call to toString())
375
//
376
if (myToString == null) {
377         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
378         result.append(this.getClass().getName());
379         result.append("(name=");
380         result.append(getTypeName());
381         result.append(",items=(");
382         int i=0;
383         Iterator JavaDoc k=nameToType.keySet().iterator();
384         String JavaDoc key;
385         while (k.hasNext()) {
386         key = (String JavaDoc) k.next();
387         if (i > 0) result.append(",");
388         result.append("(itemName=");
389         result.append(key);
390         result.append(",itemType=");
391         result.append(nameToType.get(key).toString() +")");
392         i++;
393         }
394         result.append("))");
395         myToString = result.toString();
396     }
397
398     // return always the same string representation for this instance (immutable)
399
//
400
return myToString;
401     }
402
403 }
404
405
Popular Tags