| CompositeType.java |
/*
* JBoss, the OpenSource J2EE webOS
*
* Distributable under LGPL license.
* See terms of license at gnu.org.
*/
package javax.management.openmbean;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeMap;
import java.io.Serializable;
/**
* The CompositeType is an OpenType that describes CompositeData.
*
* @see CompositeData
*
* @author <a href="mailto:Adrian.Brock@HappeningTimes.com">Adrian Brock</a>.
* @author <a href="mailto:thomas.diesler@jboss.com">Thomas Diesler</a>.
*
* @version $Revision: 1.5 $
*/
public class CompositeType
extends OpenType
implements Serializable
{
// Attributes ----------------------------------------------------
/**
* Item names to descriptions
*/
private TreeMap nameToDescription;
/**
* Item names to open types
*/
private TreeMap nameToType;
/**
* Cached hash code
*/
private transient int cachedHashCode = 0;
/**
* Cached string representation
*/
private transient String cachedToString = null;
// Static --------------------------------------------------------
private static final long serialVersionUID = -5366242454346948798L;
// Constructors --------------------------------------------------
/**
* Construct a composite type. The parameters are checked for validity.<p>
*
* The three arrays are internally copied. Future changes to these
* arrays do not alter the composite type.<p>
*
* getClassName() returns javax.management.openbean.CompositeData<p>
*
* @param typeName the name of the composite type, cannot be null or
* empty
* @param description the human readable description of the composite type,
* cannot be null or empty
* @param itemNames the names of the items described by this type. Cannot
* be null, must contain at least one element, the elements cannot
* be null or empty. The order of the items is unimportant when
* determining equality.
* @param itemDescriptions the human readable descriptions of the items
* in the same order as the itemNames, cannot be null must have the
* same number of elements as the itemNames. The elements cannot
* be null or empty.
* @param itemTypes the OpenTypes of the items in the same order as the
* item names, cannot be null must have the
* same number of elements as the itemNames. The elements cannot
* be null.
* @exception OpenDataException when itemNames contains a duplicate name.
* The names are case sensitive, leading and trailing whitespace
* is ignored.
* @exception IllegalArgumentException when a parameter does not match
* what is described above.
*/
public CompositeType(String typeName, String description,
String[] itemNames, String[] itemDescriptions,
OpenType[] itemTypes)
throws OpenDataException
{
super(CompositeData.class.getName(), typeName, description);
if (itemNames == null || itemNames.length == 0)
throw new IllegalArgumentException("null or empty itemNames");
if (itemDescriptions == null || itemDescriptions.length == 0)
throw new IllegalArgumentException("null or empty itemDescriptions");
if (itemTypes == null || itemTypes.length == 0)
throw new IllegalArgumentException("null or empty itemTypes");
if (itemNames.length != itemDescriptions.length)
throw new IllegalArgumentException("wrong number of itemDescriptions");
if (itemNames.length != itemTypes.length)
throw new IllegalArgumentException("wrong number of itemTypes");
nameToDescription = new TreeMap();
nameToType = new TreeMap();
for (int i = 0; i < itemNames.length; i++)
{
if (itemNames[i] == null)
throw new IllegalArgumentException("null item name " + i);
String itemName = itemNames[i].trim();
if (itemName.length() == 0)
throw new IllegalArgumentException("empty item name " + i);
if (nameToDescription.containsKey(itemName))
throw new OpenDataException("duplicate item name " + itemName);
if (itemDescriptions[i] == null)
throw new IllegalArgumentException("null item description " + i);
String itemDescription = itemDescriptions[i].trim();
if (itemDescription.length() == 0)
throw new IllegalArgumentException("empty item description " + i);
if (itemTypes[i] == null)
throw new IllegalArgumentException("null item type " + i);
nameToDescription.put(itemName, itemDescription);
nameToType.put(itemName, itemTypes[i]);
}
}
// Public --------------------------------------------------------
/**
* Determine whether this CompositeType contains the itemName
*
* @param itemName the item name
* @return true when it does, false otherwise
*/
public boolean containsKey(String itemName)
{
if (itemName == null)
return false;
return nameToDescription.containsKey(itemName);
}
/**
* Retrieve the description for an item name
*
* @param itemName the item name
* @return the description or null when there is no such item name
*/
public String getDescription(String itemName)
{
if (itemName == null)
return null;
return (String) nameToDescription.get(itemName);
}
/**
* Retrieve the open type for an item name
*
* @param itemName the item name
* @return the open type or null when there is no such item name
*/
public OpenType getType(String itemName)
{
if (itemName == null)
return null;
return (OpenType) nameToType.get(itemName);
}
/**
* Retrieve an unmodifiable Set view of all the item names in
* ascending order.
*
* @return the Set
*/
public Set keySet()
{
return Collections.unmodifiableSet(nameToDescription.keySet());
}
// OpenType Overrides --------------------------------------------
/**
* Determines whether the object is a value of the this composite type.<p>
*
* The object must not be null and it must be an instance of
* javax.management.openbean.CompositeData. The CompositeType of the
* CompositeData have equality with this CompositeType.
*
* @param obj the object to test
* @return the true when the above condition is satisfied, false otherwise
*/
public boolean isValue(Object obj)
{
if (obj == null || !(obj instanceof CompositeData))
return false;
return equals(((CompositeData) obj).getCompositeType());
}
/**
* Tests for equality with another composite type<p>
*
* The type names must be equal.<br>
* The item names and types are equal.
*
* @param obj the other composite type to test
* @return the true when the above condition is satisfied, false otherwise
*/
public boolean equals(Object obj)
{
if (obj == null || (obj instanceof CompositeType) == false)
return false;
if (this == obj)
return true;
CompositeType other = (CompositeType) obj;
if (this.getTypeName().equals(other.getTypeName()) == false)
return false;
Iterator thisNames = this.keySet().iterator();
Iterator otherNames = other.keySet().iterator();
while(thisNames.hasNext() && otherNames.hasNext())
{
String thisName = (String) thisNames.next();
String otherName = (String) otherNames.next();
if (thisName.equals(otherName) == false)
return false;
if (this.getType(thisName).equals(other.getType(otherName)) == false)
return false;
}
if (thisNames.hasNext() || otherNames.hasNext())
return false;
return true;
}
public int hashCode()
{
if (cachedHashCode != 0)
return cachedHashCode;
cachedHashCode = getTypeName().hashCode();
for (Iterator i = nameToType.values().iterator(); i.hasNext();)
cachedHashCode += i.next().hashCode();
for (Iterator i = nameToDescription.keySet().iterator(); i.hasNext();)
cachedHashCode += i.next().hashCode();
return cachedHashCode;
}
public String toString()
{
if (cachedToString != null)
return cachedToString;
StringBuffer buffer = new StringBuffer(getClass().getName());
buffer.append("\n");
Iterator thisNames = keySet().iterator();
while(thisNames.hasNext())
{
String thisName = (String) thisNames.next();
buffer.append("name=");
buffer.append(thisName);
buffer.append(" type=");
buffer.append(getType(thisName));
if (thisNames.hasNext())
buffer.append("\n");
}
cachedToString = buffer.toString();
return cachedToString;
}
}
| CompositeType.java |