1. /*
  2. * @(#)OpenType.java 3.27 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. package javax.management.openmbean;
  8. // java import
  9. //
  10. import java.io.IOException;
  11. import java.io.ObjectInputStream;
  12. import java.io.Serializable;
  13. // jmx import
  14. //
  15. /**
  16. * The <code>OpenType</code> class is the parent abstract class of all classes which describe the actual <i>open type</i>
  17. * of open data values.
  18. * <p>
  19. * An <i>open type</i> is defined by:
  20. * <ul>
  21. * <li>the fully qualified Java class name of the open data values this type describes;
  22. * note that only a limited set of Java classes is allowed for open data values
  23. * (see {@link #ALLOWED_CLASSNAMES ALLOWED_CLASSNAMES}),</li>
  24. * <li>its name,</li>
  25. * <li>its description.</li>
  26. * </ul>
  27. *
  28. * @version 3.27 03/12/19
  29. * @author Sun Microsystems, Inc.
  30. *
  31. * @since 1.5
  32. * @since.unbundled JMX 1.1
  33. */
  34. public abstract class OpenType implements Serializable {
  35. /* Serial version */
  36. static final long serialVersionUID = -9195195325186646468L;
  37. /**
  38. * List of the fully qualified names of the Java classes allowed for open data values.
  39. * A multidimensional array of any one of these classes is also an allowed for open data values.
  40. *
  41. <pre>ALLOWED_CLASSNAMES = {
  42. "java.lang.Void",
  43. "java.lang.Boolean",
  44. "java.lang.Character",
  45. "java.lang.Byte",
  46. "java.lang.Short",
  47. "java.lang.Integer",
  48. "java.lang.Long",
  49. "java.lang.Float",
  50. "java.lang.Double",
  51. "java.lang.String",
  52. "java.math.BigDecimal",
  53. "java.math.BigInteger",
  54. "java.util.Date",
  55. "javax.management.ObjectName",
  56. CompositeData.class.getName(),
  57. TabularData.class.getName() } ;
  58. </pre>
  59. *
  60. */
  61. public static final String[] ALLOWED_CLASSNAMES = {
  62. "java.lang.Void",
  63. "java.lang.Boolean",
  64. "java.lang.Character",
  65. "java.lang.Byte",
  66. "java.lang.Short",
  67. "java.lang.Integer",
  68. "java.lang.Long",
  69. "java.lang.Float",
  70. "java.lang.Double",
  71. "java.lang.String",
  72. "java.math.BigDecimal",
  73. "java.math.BigInteger",
  74. "java.util.Date",
  75. "javax.management.ObjectName",
  76. CompositeData.class.getName(), // better refer to these two class names like this, rather than hardcoding a string,
  77. TabularData.class.getName() } ; // in case the package of these classes should change (who knows...)
  78. /**
  79. * @serial The fully qualified Java class name of open data values this type describes.
  80. */
  81. private String className;
  82. /**
  83. * @serial The type description (should not be null or empty).
  84. */
  85. private String description;
  86. /**
  87. * @serial The name given to this type (should not be null or empty).
  88. */
  89. private String typeName;
  90. /**
  91. * @serial Tells if this type describes an array (checked in constructor).
  92. */
  93. private transient boolean isArray = false;
  94. /* *** Constructor *** */
  95. /**
  96. * Constructs an <code>OpenType</code> instance (actually a subclass instance as <code>OpenType</code> is abstract),
  97. * checking for the validity of the given parameters.
  98. * The validity constraints are described below for each parameter.
  99. * <br> 
  100. * @param className The fully qualified Java class name of the open data values this open type describes.
  101. * The valid Java class names allowed for open data values are listed in
  102. * {@link #ALLOWED_CLASSNAMES ALLOWED_CLASSNAMES}.
  103. * A multidimensional array of any one of these classes is also an allowed class,
  104. * in which case the class name follows the rules defined by the method
  105. * {@link Class#getName() getName()} of <code>java.lang.Class</code>.
  106. * For example, a 3-dimensional array of Strings has for class name
  107. * "<code>[[[Ljava.lang.String;</code>" (without the quotes).
  108. * <br> 
  109. * @param typeName The name given to the open type this instance represents; cannot be a null or empty string.
  110. * <br> 
  111. * @param description The human readable description of the open type this instance represents;
  112. * cannot be a null or empty string.
  113. * <br> 
  114. * @throws IllegalArgumentException if <var>className</var>, <var>typeName</var> or <var>description</var>
  115. * is a null or empty string
  116. * <br> 
  117. * @throws OpenDataException if <var>className</var> is not one of the allowed Java class names for open data
  118. */
  119. protected OpenType(String className,
  120. String typeName,
  121. String description) throws OpenDataException {
  122. // Check parameters that cannot be null or empty
  123. //
  124. if ( (className == null) || (className.trim().equals("")) ) {
  125. throw new IllegalArgumentException("Argument className cannot be null or empty.");
  126. }
  127. if ( (typeName == null) || (typeName.trim().equals("")) ) {
  128. throw new IllegalArgumentException("Argument typeName cannot be null or empty.");
  129. }
  130. if ( (description == null) || (description.trim().equals("")) ) {
  131. throw new IllegalArgumentException("Argument description cannot be null or empty.");
  132. }
  133. // remove leading and trailing white spaces, if any
  134. //
  135. className = className.trim();
  136. typeName = typeName.trim();
  137. description = description.trim();
  138. // Check if className describes an array class, and determines its elements' class name.
  139. // (eg: a 3-dimensional array of Strings has for class name: "[[[Ljava.lang.String;")
  140. //
  141. int n = 0;
  142. while (className.startsWith("[", n)) {
  143. n++;
  144. }
  145. String eltClassName; // class name of array elements
  146. boolean isArray = false;
  147. if (n > 0) {
  148. // removes the n leading '[' + the 'L' characters and the last ';' character
  149. eltClassName = className.substring(n+1, className.length()-1); // see javadoc of String.substring(begin,end)
  150. isArray = true;
  151. } else {
  152. // not an array
  153. eltClassName = className;
  154. }
  155. // Check that eltClassName's value is one of the allowed basic data types for open data
  156. //
  157. boolean ok = false;
  158. for (int i=0; i<ALLOWED_CLASSNAMES.length; i++) {
  159. if (ALLOWED_CLASSNAMES[i].equals(eltClassName)) {
  160. ok = true;
  161. break;
  162. }
  163. }
  164. if ( ! ok ) {
  165. throw new OpenDataException("Argument className=\""+ className +
  166. "\" is not one of the allowed Java class names for open data.");
  167. }
  168. // Now initializes this OpenType instance
  169. //
  170. this.className = className;
  171. this.typeName = typeName;
  172. this.description = description;
  173. this.isArray = isArray;
  174. }
  175. /* *** Open type information methods *** */
  176. /**
  177. * Returns the fully qualified Java class name of the open data values this open type describes.
  178. * The only possible Java class names for open data values are listed in
  179. * {@link #ALLOWED_CLASSNAMES ALLOWED_CLASSNAMES}.
  180. * A multidimensional array of any one of these classes is also an allowed class,
  181. * in which case the class name follows the rules defined by the method
  182. * {@link Class#getName() getName()} of <code>java.lang.Class</code>.
  183. * For example, a 3-dimensional array of Strings has for class name
  184. * "<code>[[[Ljava.lang.String;</code>" (without the quotes).
  185. *
  186. * @return the class name.
  187. */
  188. public String getClassName() {
  189. return className;
  190. }
  191. /**
  192. * Returns the name of this <code>OpenType</code> instance.
  193. *
  194. * @return the type name.
  195. */
  196. public String getTypeName() {
  197. return typeName;
  198. }
  199. /**
  200. * Returns the text description of this <code>OpenType</code> instance.
  201. *
  202. * @return the description.
  203. */
  204. public String getDescription() {
  205. return description;
  206. }
  207. /**
  208. * Returns <code>true</code> if the open data values this open
  209. * type describes are arrays, <code>false</code> otherwise.
  210. *
  211. * @return true if this is an array type.
  212. */
  213. public boolean isArray() {
  214. return isArray;
  215. }
  216. /**
  217. * Tests whether <var>obj</var> is a value for this open type.
  218. *
  219. * @param obj the object to be tested for validity.
  220. *
  221. * @return <code>true</code> if <var>obj</var> is a value for this
  222. * open type, <code>false</code> otherwise.
  223. */
  224. public abstract boolean isValue(Object obj) ;
  225. /* *** Methods overriden from class Object *** */
  226. /**
  227. * Compares the specified <code>obj</code> parameter with this
  228. * open type instance for equality.
  229. *
  230. * @param obj the object to compare to.
  231. *
  232. * @return true if this object and <code>obj</code> are equal.
  233. */
  234. public abstract boolean equals(Object obj) ;
  235. public abstract int hashCode() ;
  236. /**
  237. * Returns a string representation of this open type instance.
  238. *
  239. * @return the string representation.
  240. */
  241. public abstract String toString() ;
  242. /**
  243. * Deserializes an {@link OpenType} from an {@link ObjectInputStream}.
  244. */
  245. private void readObject(ObjectInputStream in)
  246. throws IOException, ClassNotFoundException {
  247. in.defaultReadObject();
  248. isArray = (className.startsWith("["));
  249. }
  250. }