FileDocCategorySizeDatePackage
ArrayType.javaAPI DocJava SE 5 API14309Fri Aug 26 14:57:36 BST 2005javax.management.openmbean

ArrayType

public class ArrayType extends OpenType implements Serializable
The ArrayType class is the open type class whose instances describe all open data values which are n-dimensional arrays of open data values.
version
3.24 03/12/19
author
Sun Microsystems, Inc.
since
1.5
since.unbundled
JMX 1.1

Fields Summary
static final long
serialVersionUID
private int
dimension
private OpenType
elementType
private transient Integer
myHashCode
private transient String
myToString
Constructors Summary
public ArrayType(int dimension, OpenType elementType)
Constructs an ArrayType instance describing open data values which are arrays with dimension dimension of elements whose open type is elementType.

When invoked on an ArrayType instance, the {@link OpenType#getClassName() getClassName} method returns the class name of the array instances it describes (following the rules defined by the {@link Class#getName() getName} method of java.lang.Class), not the class name of the array elements (which is returned by a call to getElementOpenType().getClassName()).

The internal field corresponding to the type name of this ArrayType instance is also set to the class name of the array instances it describes. In other words, the methods getClassName and getTypeName return the same string value. The internal field corresponding to the description of this ArrayType instance is set to a string value which follows the following template:
<dimension>-dimension array of <element_class_name>

As an example, the following piece of code:

ArrayType t = new ArrayType(3, SimpleType.STRING);
System.out.println("array class name = "+ t.getClassName());
System.out.println("element class name = "+ t.getElementOpenType().getClassName());
System.out.println("array type name = "+ t.getTypeName());
System.out.println("array type description = "+ t.getDescription());
would produce the following output:
array class name = [[[java.lang.String;
element class name = java.lang.String
array type name = [[[java.lang.String;
array type description = 3-dimension array of java.lang.String

param
dimension the dimension of arrays described by this ArrayType instance; must be greater than or equal to 1.
param
elementType the open type of element values contained in the arrays described by this ArrayType instance; must be an instance of either SimpleType, CompositeType or TabularType.
throws
IllegalArgumentException if dimension is not a positive integer
throws
OpenDataException if elementType is an instance of ArrayType

	// need only be calculated once.


    /* *** Constructor *** */

                                                                                                                                                                                                                                                                      			                         			            			                                
           
		         
	
	// Check and construct state defined by parent.
	//
	super(buildArrayClassName(dimension, elementType.getClassName()), 
	      buildArrayClassName(dimension, elementType.getClassName()), 
	      String.valueOf(dimension) +"-dimension array of "+ elementType.getClassName());
	
	// Check and construct state specific to ArrayType
	//
	this.dimension   = dimension;   // already checked >=1 in buildArrayClassName
	this.elementType = elementType; // cannot be ArrayType: super() would throw exception on the built classname
    
Methods Summary
private static java.lang.StringbuildArrayClassName(int dimension, java.lang.String elementClassName)


	if (dimension < 1) {
	    throw new IllegalArgumentException("Value of argument dimension must be greater than 0");
	}

	StringBuffer result = new StringBuffer();

	for (int i=1; i<dimension; i++) { // add (dimension - 1) '[' characters
	    result.append('[");
	}
	result.append("[L");
	result.append(elementClassName);
	result.append(';");

	return result.toString();
    
private booleancheckElementsType(java.lang.Object[] x_dim_Array, int dim)
Returns true if and only if all elements contained in the array argument x_dim_Array of dimension dim are valid values (ie either null or of the right openType) for the element open type specified by this ArrayType instance. This method's implementation uses recursion to go down the dimensions of the array argument.


	// if the elements of x_dim_Array are themselves array: go down recursively....
	if ( dim > 1 ) {
	    for (int i=0; i<x_dim_Array.length; i++) {
		if ( ! checkElementsType((Object[])x_dim_Array[i], dim-1) ) {
		    return false;
		}
	    }
	    return true;
	}
	// ...else, for a non-empty array, each element must be a valid value: either null or of the right openType
	else {
	    for (int i=0; i<x_dim_Array.length; i++) {
		if ( (x_dim_Array[i] != null) && (! this.getElementOpenType().isValue(x_dim_Array[i])) ) {
		    return false;
		}
	    }
	    return true;
	}
    
public booleanequals(java.lang.Object obj)
Compares the specified obj parameter with this ArrayType instance for equality.

Two ArrayType instances are equal if and only if they describes array instances which have the same dimension and elements' open type.

param
obj the object to be compared for equality with this ArrayType instance; if obj is null or is not an instance of the class ArrayType, equals returns false.
return
true if the specified object is equal to this ArrayType instance.


	// if obj is null, return false
	//
	if (obj == null) {
	    return false;
	}

	// if obj is not an ArrayType, return false
	//
	ArrayType other;
	try {
	    other = (ArrayType) obj;
	} catch (ClassCastException e) {
	    return false;
	}

	// if other's dimension is different than this instance's, return false
	//
	if (other.dimension != this.dimension) {
	    return false;
	}

	// Test if other's elementType field is the same as for this instance
	//
	return this.elementType.equals(other.elementType);
    
public intgetDimension()
Returns the dimension of arrays described by this ArrayType instance.

return
the dimension.


	return dimension;
    
public javax.management.openmbean.OpenTypegetElementOpenType()
Returns the open type of element values contained in the arrays described by this ArrayType instance.

return
the element type.


	return elementType;
    
public inthashCode()
Returns the hash code value for this ArrayType instance.

The hash code of a ArrayType instance is the sum of the hash codes of all elements of information used in equals comparisons (ie: dimension and elements' type). This ensures that t1.equals(t2) implies that t1.hashCode()==t2.hashCode() for any two ArrayType instances t1 and t2, as required by the general contract of the method {@link Object#hashCode() Object.hashCode()}.

As ArrayType instances are immutable, the hash code for this instance is calculated once, on the first call to hashCode, and then the same value is returned for subsequent calls.

return
the hash code value for this ArrayType instance


	// Calculate the hash code value if it has not yet been done (ie 1st call to hashCode())
	//
	if (myHashCode == null) {
	    int value = 0;
	    value += this.dimension;
	    value += this.elementType.hashCode();
	    myHashCode = new Integer(value);
	}
	
	// return always the same hash code for this instance (immutable)
	//
	return myHashCode.intValue();
    
public booleanisValue(java.lang.Object obj)
Tests whether obj is a value for this ArrayType instance.

This method returns true if and only if obj is not null, obj is an array and any one of the following is true:

  • if this ArrayType instance describes an array of SimpleType elements, obj's class name is the same as the className field defined for this ArrayType instance (ie the class name returned by the {@link OpenType#getClassName() getClassName} method, which includes the dimension information),
     
  • if this ArrayType instance describes an array of classes implementing the TabularData interface or the CompositeData interface, obj is assignable to such a declared array, and each element contained in obj is either null or a valid value for the element's open type specified by this ArrayType instance.

param
obj the object to be tested.
return
true if obj is a value for this ArrayType instance.


	// if obj is null, return false
	//
	if (obj == null) {
	    return false;
	}

	Class  objClass     = obj.getClass();
	String objClassName = objClass.getName();

	// if obj is not an array, return false
	//
	if ( ! objClass.isArray() ) {
	    return false;
	}

	// Test if obj's class name is the same as for the array values that this instance describes
	// (this is fine if elements are of simple types, which are final classes)
	//
	if ( this.getClassName().equals(objClassName) ) {
	    return true;
	}

	// In case this ArrayType instance describes an array of classes implementing the TabularData or CompositeData interface,
	// we first check for the assignability of obj to such an array of TabularData or CompositeData, 
	// which ensures that:
	//  . obj is of the the same dimension as this ArrayType instance, 
	//  . it is declared as an array of elements which are either all TabularData or all CompositeData.
	//
	// If the assignment check is positive, 
	// then we have to check that each element in obj is of the same TabularType or CompositeType 
	// as the one described by this ArrayType instance.
	//
	// [About assignment check, note that the call below returns true: ]
	// [Class.forName("[Lpackage.CompositeData;").isAssignableFrom(Class.forName("[Lpackage.CompositeDataImpl;)")); ]
	//
	if ( (this.elementType.getClassName().equals(TabularData.class.getName()))  ||
	     (this.elementType.getClassName().equals(CompositeData.class.getName()))   ) {

	    /* this.getClassName() is
	     * "[Ljavax.management.openmbean.TabularData;" or the same
	     * thing for CompositeData, either one optionally preceded
	     * by n '[' characters.  So the class is necessarily known
	     * to the ClassLoader of ArrayType, and Class.forName is
	     * safe.  */
	    Class targetClass;
	    try {
		targetClass = Class.forName(this.getClassName());
	    } catch (ClassNotFoundException e) { // should not happen 
		return false; 
	    }
	    // assignment check: return false if negative
	    if  ( ! targetClass.isAssignableFrom(objClass) ) {
		return false;
	    }

	    // check that all elements in obj are valid values for this ArrayType
	    if ( ! checkElementsType( (Object[]) obj, this.dimension) ) { // we know obj's dimension is this.dimension
		return false;
	    }

	    return true;
	}

	// if previous tests did not return, then obj is not a value for this ArrayType instance
	return false;
    
public java.lang.StringtoString()
Returns a string representation of this ArrayType instance.

The string representation consists of the name of this class (ie javax.management.openmbean.ArrayType), the type name, the dimension and elements' type defined for this instance,

As ArrayType instances are immutable, the string representation for this instance is calculated once, on the first call to toString, and then the same value is returned for subsequent calls.

return
a string representation of this ArrayType instance


	// Calculate the string representation if it has not yet been done (ie 1st call to toString())
	//
	if (myToString == null) {
	    StringBuffer result = new StringBuffer();
	    result.append(this.getClass().getName());
	    result.append("(name=");
	    result.append(getTypeName());
	    result.append(",dimension=");
	    result.append(String.valueOf(this.dimension));
	    result.append(",elementType=");
	    result.append(this.elementType.toString());
	    result.append(")");
	    myToString = result.toString();
	}

	// return always the same string representation for this instance (immutable)
	//
	return myToString;