001: /* JFox, the OpenSource J2EE Application Server
002: *
003: * Copyright (C) 2002 huihoo.org
004: * Distributable under GNU LGPL license
005: * See the GNU Lesser General Public License for more details.
006: */
007:
008: package javax.management.openmbean;
009:
010: import java.io.Serializable;
011: import java.io.IOException;
012: import java.io.ObjectInputStream;
013: import javax.management.openmbean.OpenDataException;
014:
015: /**
016: * The <code>OpenType</code> class is the parent abstract class of all classes which describe the actual <i>open type</i>
017: * of open data values.
018: * <p>
019: * An <i>open type</i> is defined by:
020: * <ul>
021: * <li>the fully qualified Java class name of the open data values this type describes;
022: * note that only a limited set of Java classes is allowed for open data values
023: * (see {@link #ALLOWED_CLASSNAMES ALLOWED_CLASSNAMES}),</li>
024: * <li>its name,</li>
025: * <li>its description.</li>
026: * </ul>
027: *
028: * @author <a href="mailto:young_yy@hotmail.org">Young Yang</a>
029: */
030:
031: public abstract class OpenType implements Serializable {
032:
033: protected static final String VOID_CLASSNAME = java.lang.Void.class
034: .getName();
035: protected static final String BOOLEAN_CLASSNAME = java.lang.Boolean.class
036: .getName();
037: protected static final String CHARACTER_CLASSNAME = java.lang.Character.class
038: .getName();
039: protected static final String BYTE_CLASSNAME = java.lang.Byte.class
040: .getName();
041: protected static final String SHORT_CLASSNAME = java.lang.Short.class
042: .getName();
043: protected static final String INTEGER_CLASSNAME = java.lang.Integer.class
044: .getName();
045: protected static final String LONG_CLASSNAME = java.lang.Long.class
046: .getName();
047: protected static final String FLOAT_CLASSNAME = java.lang.Float.class
048: .getName();
049: protected static final String DOUBLE_CLASSNAME = java.lang.Double.class
050: .getName();
051: protected static final String STRING_CLASSNAME = java.lang.String.class
052: .getName();
053: protected static final String BIGDECIMAL_CLASSNAME = java.math.BigDecimal.class
054: .getName();
055: protected static final String BIGINTEGER_CLASSNAME = java.math.BigInteger.class
056: .getName();
057: protected static final String OBJECTNAME_CLASSNAME = javax.management.ObjectName.class
058: .getName();
059: protected static final String COMPOSITEDATA_CLASSNAME = javax.management.openmbean.CompositeData.class
060: .getName();
061: protected static final String TABULARDATA_CLASSNAME = javax.management.openmbean.TabularData.class
062: .getName();
063: protected static final String DATE_CLASSNAME = java.util.Date.class
064: .getName();
065:
066: /**
067: * List of the fully qualified names of the Java classes allowed for open data values.
068: * A multidimensional array of any one of these classes is also an allowed for open data values.
069: *
070: <pre>ALLOWED_CLASSNAMES = {
071: "java.lang.Void",
072: "java.lang.Boolean",
073: "java.lang.Character",
074: "java.lang.Byte",
075: "java.lang.Short",
076: "java.lang.Integer",
077: "java.lang.Long",
078: "java.lang.Float",
079: "java.lang.Double",
080: "java.lang.String",
081: "java.math.BigDecimal",
082: "java.math.BigInteger",
083: "java.util.Date",
084: "javax.management.ObjectName",
085: CompositeData.class.getNameSpace(),
086: TabularData.class.getNameSpace() } ;
087: </pre>
088: *
089: */
090: public static final String[] ALLOWED_CLASSNAMES = new String[] {
091: VOID_CLASSNAME, BOOLEAN_CLASSNAME, CHARACTER_CLASSNAME,
092: BYTE_CLASSNAME, SHORT_CLASSNAME, INTEGER_CLASSNAME,
093: LONG_CLASSNAME, FLOAT_CLASSNAME, DOUBLE_CLASSNAME,
094: STRING_CLASSNAME, BIGDECIMAL_CLASSNAME,
095: BIGINTEGER_CLASSNAME, OBJECTNAME_CLASSNAME,
096: COMPOSITEDATA_CLASSNAME, TABULARDATA_CLASSNAME };
097: /**
098: * @serial The fully qualified Java class name of open data values this type describes.
099: */
100: private String className;
101:
102: /**
103: * @serial The type description (should not be null or empty).
104: */
105: private String description;
106:
107: /**
108: * @serial The name given to this type (should not be null or empty).
109: */
110: private String typeName;
111:
112: /**
113: * @serial Tells if this type describes an array (checked in constructor).
114: */
115: private transient boolean isArray = false;
116:
117: /* *** Constructor *** */
118:
119: /**
120: * Constructs an <code>OpenType</code> instance (actually a subclass instance as <code>OpenType</code> is abstract),
121: * checking for the validity of the given parameters.
122: * The validity constraints are described below for each parameter.
123: * <br>
124: * @param className The fully qualified Java class name of the open data values this open type describes.
125: * The valid Java class names allowed for open data values are listed in
126: * {@link #ALLOWED_CLASSNAMES ALLOWED_CLASSNAMES}.
127: * A multidimensional array of any one of these classes is also an allowed class,
128: * in which case the class name follows the rules defined by the method
129: * {@link <a href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Class.html#getNameSpace()">
130: * <code>getNameSpace</code></a>} of <code>java.lang.Class</code>.
131: * For example, a 3-dimensional array of Strings has for class name
132: * "<code>[[[Ljava.lang.String;</code>" (without the quotes).
133: * <br>
134: * @param typeName The name given to the open type this instance represents; cannot be a null or empty string.
135: * <br>
136: * @param description The human readable description of the open type this instance represents;
137: * cannot be a null or empty string.
138: * <br>
139: * @throws IllegalArgumentException if <var>className</var>, <var>typeName</var> or <var>description</var>
140: * is a null or empty string
141: * <br>
142: * @throws OpenDataException if <var>className</var> is not one of the allowed Java class names for open data
143: */
144: protected OpenType(String className, String typeName,
145: String description) throws OpenDataException {
146:
147: // Check parameters that cannot be null or empty
148: //
149: if ((className == null) || (className.trim().equals(""))) {
150: throw new IllegalArgumentException(
151: "Argument className cannot be null or empty.");
152: }
153: if ((typeName == null) || (typeName.trim().equals(""))) {
154: throw new IllegalArgumentException(
155: "Argument typeName cannot be null or empty.");
156: }
157: if ((description == null) || (description.trim().equals(""))) {
158: throw new IllegalArgumentException(
159: "Argument description cannot be null or empty.");
160: }
161:
162: // remove leading and trailing white spaces, if any
163: //
164: className = className.trim();
165: typeName = typeName.trim();
166: description = description.trim();
167:
168: // Check if className describes an array class, and determines its elements' class name.
169: // (eg: a 3-dimensional array of Strings has for class name: "[[[Ljava.lang.String;")
170: //
171: int n = 0;
172: while (className.startsWith("[", n)) {
173: n++;
174: }
175: String eltClassName; // class name of array elements
176: boolean isArray = false;
177: if (n > 0) {
178: // removes the n leading '[' + the 'L' characters and the last ';' character
179: eltClassName = className.substring(n + 1, className
180: .length() - 1); // see javadoc of String.substring(begin,end)
181: isArray = true;
182: } else {
183: // not an array
184: eltClassName = className;
185: }
186:
187: // Check that eltClassName's value is one of the allowed basic data types for open data
188: //
189: boolean ok = false;
190: for (int i = 0; i < ALLOWED_CLASSNAMES.length; i++) {
191: if (ALLOWED_CLASSNAMES[i].equals(eltClassName)) {
192: ok = true;
193: break;
194: }
195: }
196: if (!ok) {
197: throw new OpenDataException(
198: "Argument className=\""
199: + className
200: + "\" is not one of the allowed Java class names for open data.");
201: }
202:
203: // Now initializes this OpenType instance
204: //
205: this .className = className;
206: this .typeName = typeName;
207: this .description = description;
208: this .isArray = isArray;
209: }
210:
211: /* *** Open type information methods *** */
212:
213: /**
214: * Returns the fully qualified Java class name of the open data values this open type describes.
215: * The only possible Java class names for open data values are listed in
216: * {@link #ALLOWED_CLASSNAMES ALLOWED_CLASSNAMES}.
217: * A multidimensional array of any one of these classes is also an allowed class,
218: * in which case the class name follows the rules defined by the method
219: * {@link <a href="http://java.sun.com/j2se/1.3/docs/api/java/lang/Class.html#getNameSpace()">
220: * <code>getNameSpace</code></a>} of <code>java.lang.Class</code>.
221: * For example, a 3-dimensional array of Strings has for class name
222: * "<code>[[[Ljava.lang.String;</code>" (without the quotes).
223: *
224: * @return the class name.
225: */
226: public String getClassName() {
227:
228: return className;
229: }
230:
231: /**
232: * Returns the name of this <code>OpenType</code> instance.
233: *
234: * @return the type name.
235: */
236: public String getTypeName() {
237:
238: return typeName;
239: }
240:
241: /**
242: * Returns the text description of this <code>OpenType</code> instance.
243: *
244: * @return the description.
245: */
246: public String getDescription() {
247:
248: return description;
249: }
250:
251: /**
252: * Returns <code>true</code> if the open data values this open
253: * type describes are arrays, <code>false</code> otherwise.
254: *
255: * @return true if this is an array type.
256: */
257: public boolean isArray() {
258:
259: return isArray;
260: }
261:
262: /**
263: * Tests whether <var>obj</var> is a value for this open type.
264: *
265: * @param obj the object to be tested for validity.
266: *
267: * @return <code>true</code> if <var>obj</var> is a value for this
268: * open type, <code>false</code> otherwise.
269: */
270: public abstract boolean isValue(Object obj);
271:
272: /* *** Methods overriden from class Object *** */
273:
274: /**
275: * Compares the specified <code>obj</code> parameter with this
276: * open type instance for equality.
277: *
278: * @param obj the object to compare to.
279: *
280: * @return true if this object and <code>obj</code> are equal.
281: */
282: public abstract boolean equals(Object obj);
283:
284: public abstract int hashCode();
285:
286: /**
287: * Returns a string representation of this open type instance.
288: *
289: * @return the string representation.
290: */
291: public abstract String toString();
292:
293: /**
294: * Deserializes an {@link OpenType} from an {@link ObjectInputStream}.
295: */
296: private void readObject(ObjectInputStream in) throws IOException,
297: ClassNotFoundException {
298: in.defaultReadObject();
299: isArray = (className.startsWith("["));
300: }
301: }
|