001: /**
002: * Copyright (C) The MX4J Contributors.
003: * All rights reserved.
004: *
005: * This software is distributed under the terms of the MX4J License version 1.0.
006: * See the terms of the MX4J License in the documentation provided with this software.
007: */package javax.management.openmbean;
008:
009: import java.io.Serializable;
010:
011: /**
012: * The ArrayType class is the open type class whose instances describe all open data values
013: * which are n-dimensional arrays of open data values
014: *
015: * @version $Revision: 1.13 $
016: */
017: public class ArrayType extends OpenType implements Serializable {
018: private static final long serialVersionUID = 720504429830309770L;
019:
020: /**
021: * The dimension of the ArrayType
022: */
023: private int dimension = 0;
024: /**
025: * The OpenType elemement of this ArrayType
026: */
027: private OpenType elementType = null;
028:
029: //transient fields
030: private transient int hashCode = 0;
031:
032: /**
033: * Constructs an ArrayType instance describing open data values
034: * which are arrays with dimension dimension of elements whose
035: * open type is elementType.
036: *
037: * @param dimension The dimension of this ArrayType and should be greater
038: * than 0;
039: * @param elementType The OpenType element of this ArrayType
040: * @throws OpenDataException if elementType is instance of ArrayType
041: * @throws IllegalArgumentException if dimension is less than or zero
042: */
043: public ArrayType(int dimension, OpenType elementType)
044: throws OpenDataException {
045: super (createArrayName(elementType, dimension), createArrayName(
046: elementType, dimension), createDescription(elementType,
047: dimension));
048:
049: //shouldn't it passed on the first test already?
050: if (elementType instanceof ArrayType)
051: throw new OpenDataException(
052: "elementType can't be instance of ArrayType");
053:
054: if (dimension <= 0)
055: throw new IllegalArgumentException(
056: "int type dimension must be greater than or equal to 1");
057:
058: this .dimension = dimension;
059: this .elementType = elementType;
060:
061: }
062:
063: /**
064: * Returns the Dimension described by this ArrayType
065: *
066: * @return int The dimension
067: */
068: public int getDimension() {
069: return dimension;
070: }
071:
072: /**
073: * Returns the OpenType of element values contained in
074: * in the arrays described by this ArrayType instance
075: *
076: * @return OpenType The <code>OpenType</code> instance
077: */
078: public OpenType getElementOpenType() {
079: return elementType;
080: }
081:
082: /**
083: * Test whether object is a value for this <code>ArrayType</code> instance.
084: *
085: * @return boolean True if object is a value
086: */
087: public boolean isValue(Object object) {
088: if (object == null || !object.getClass().isArray()) {
089: return false;
090: }
091:
092: if (elementType instanceof SimpleType) {
093: return getClassName().equals(object.getClass().getName());
094: }
095:
096: if (elementType instanceof TabularType
097: || elementType instanceof CompositeType) {
098: try {
099: Class elementClass = Thread.currentThread()
100: .getContextClassLoader().loadClass(
101: getClassName());
102: if (elementClass.isAssignableFrom(object.getClass())) {
103: return checkElements((Object[]) object, dimension);
104: }
105: } catch (ClassNotFoundException x) {
106: return false;
107: }
108: }
109: return false;
110: }
111:
112: /**
113: * Check if object is equal with this ArrayType
114: *
115: * @return true If Equal
116: */
117: public boolean equals(Object object) {
118: if (object == null)
119: return false;
120: if (object == this )
121: return true;
122:
123: if (object != null) {
124:
125: if (object instanceof ArrayType) {
126: ArrayType checkedType = (ArrayType) object;
127:
128: if (checkedType.dimension != dimension)
129: return false;
130: if (getElementOpenType().equals(
131: checkedType.getElementOpenType()))
132: return true;
133: }
134: }
135: return false;
136: }
137:
138: /**
139: * Compute the hashCode of this ArrayType
140: *
141: * @return int The computed hashCode
142: */
143: public int hashCode() {
144: if (hashCode == 0) {
145: computeHashCode();
146: }
147: return hashCode;
148: }
149:
150: /**
151: * Format this ArrayType is a String
152: *
153: * @return String The readable format
154: */
155: public String toString() {
156:
157: StringBuffer sb = new StringBuffer();
158: sb.append(elementType.getClassName());
159: sb.append("(typename=");
160: sb.append(getTypeName());
161: sb.append(",dimension=");
162: sb.append("" + dimension);
163: sb.append(",elementType=");
164: sb.append(elementType.toString());
165: sb.append(")");
166:
167: return sb.toString();
168:
169: }
170:
171: /**
172: * Returns a Description
173: */
174: private static String createDescription(OpenType type, int size) {
175: StringBuffer sb = new StringBuffer("" + size);
176: sb.append("-dimension array of ");
177: sb.append(type.getClassName());
178: return sb.toString();
179:
180: }
181:
182: private static String createArrayName(OpenType type, int size) {
183: if (size <= 0)
184: throw new IllegalArgumentException(
185: "int type dimension must be greater than or equal to 1");
186: StringBuffer sb = new StringBuffer();
187: for (int i = 0; i < size; i++)
188: sb.append("[");
189: sb.append("L");
190: sb.append(type.getClassName());
191: sb.append(";");
192: return sb.toString();
193: }
194:
195: private void computeHashCode() {
196: hashCode = (dimension + elementType.hashCode());
197: }
198:
199: private boolean checkElements(Object[] array, int dim) {
200: if (dim == 1) {
201: OpenType arrayType = getElementOpenType();
202: for (int i = 0; i < array.length; i++) {
203: Object o = array[i];
204: if (o != null && !arrayType.isValue(o)) {
205: return false;
206: }
207: }
208: return true;
209: } else {
210: for (int i = 0; i < array.length; i++) {
211: Object o = array[i];
212: if (o != null && !checkElements((Object[]) o, dim - 1)) {
213: return false;
214: }
215: }
216: return true;
217: }
218: }
219: }
|