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.ObjectStreamException;
012: import java.io.InvalidObjectException;
013: import java.util.HashMap;
014: import java.util.Map;
015:
016: /**
017: * The <code>SimpleType</code> class is the <i>open type</i> class whose instances describe
018: * all <i>open data</i> values which are neither arrays,
019: * nor {@link CompositeData <code>CompositeData</code>} values,
020: * nor {@link TabularData <code>TabularData</code>} values.
021: * It predefines all its possible instances as static fields, and has no public constructor.
022: * <p>
023: * Given a <code>SimpleType</code> instance describing values whose Java class name is <i>className</i>,
024: * the internal fields corresponding to the name and description of this <code>SimpleType</code> instance
025: * are also set to <i>className</i>.
026: * In other words, its methods <code>getClassName</code>, <code>getTypeName</code> and <code>getDescription</code>
027: * all return the same string value <i>className</i>.
028: *
029: * @author <a href="mailto:young_yy@hotmail.org">Young Yang</a>
030: */
031:
032: public final class SimpleType extends OpenType implements Serializable {
033:
034: // SimpleType instances.
035: // IF YOU ADD A SimpleType, YOU MUST UPDATE OpenType and typeArray
036:
037: /**
038: * The <code>SimpleType</code> instance describing values whose
039: * Java class name is <code>java.lang.Void</code>.
040: */
041: public static final SimpleType VOID;
042:
043: /**
044: * The <code>SimpleType</code> instance describing values whose
045: * Java class name is <code>java.lang.Boolean</code>.
046: */
047: public static final SimpleType BOOLEAN;
048:
049: /**
050: * The <code>SimpleType</code> instance describing values whose
051: * Java class name is <code>java.lang.Character</code>.
052: */
053: public static final SimpleType CHARACTER;
054:
055: /**
056: * The <code>SimpleType</code> instance describing values whose
057: * Java class name is <code>java.lang.Byte</code>.
058: */
059: public static final SimpleType BYTE;
060:
061: /**
062: * The <code>SimpleType</code> instance describing values whose
063: * Java class name is <code>java.lang.Short</code>.
064: */
065: public static final SimpleType SHORT;
066:
067: /**
068: * The <code>SimpleType</code> instance describing values whose
069: * Java class name is <code>java.lang.Integer</code>.
070: */
071: public static final SimpleType INTEGER;
072:
073: /**
074: * The <code>SimpleType</code> instance describing values whose
075: * Java class name is <code>java.lang.Long</code>.
076: */
077: public static final SimpleType LONG;
078:
079: /**
080: * The <code>SimpleType</code> instance describing values whose
081: * Java class name is <code>java.lang.Float</code>.
082: */
083: public static final SimpleType FLOAT;
084:
085: /**
086: * The <code>SimpleType</code> instance describing values whose
087: * Java class name is <code>java.lang.Double</code>.
088: */
089: public static final SimpleType DOUBLE;
090:
091: /**
092: * The <code>SimpleType</code> instance describing values whose
093: * Java class name is <code>java.lang.String</code>.
094: */
095: public static final SimpleType STRING;
096:
097: /**
098: * The <code>SimpleType</code> instance describing values whose
099: * Java class name is <code>java.math.BigDecimal</code>.
100: */
101: public static final SimpleType BIGDECIMAL;
102:
103: /**
104: * The <code>SimpleType</code> instance describing values whose
105: * Java class name is <code>java.math.BigInteger</code>.
106: */
107: public static final SimpleType BIGINTEGER;
108:
109: /**
110: * The <code>SimpleType</code> instance describing values whose
111: * Java class name is <code>java.util.Date</code>.
112: */
113: public static final SimpleType DATE;
114:
115: /**
116: * The <code>SimpleType</code> instance describing values whose
117: * Java class name is <code>javax.management.ObjectName</code>.
118: */
119: public static final SimpleType OBJECTNAME;
120:
121: // Static initialization block of all possible instances of simple types
122: //
123: static {
124: SimpleType t;
125: try {
126: t = new SimpleType(VOID_CLASSNAME);
127: } catch (OpenDataException e) {
128: t = null; // should not happen
129: }
130: VOID = t;
131: try {
132: t = new SimpleType(BOOLEAN_CLASSNAME);
133: } catch (OpenDataException e) {
134: t = null; // should not happen
135: }
136: BOOLEAN = t;
137: try {
138: t = new SimpleType(CHARACTER_CLASSNAME);
139: } catch (OpenDataException e) {
140: t = null; // should not happen
141: }
142: CHARACTER = t;
143: try {
144: t = new SimpleType(BYTE_CLASSNAME);
145: } catch (OpenDataException e) {
146: t = null; // should not happen
147: }
148: BYTE = t;
149: try {
150: t = new SimpleType(SHORT_CLASSNAME);
151: } catch (OpenDataException e) {
152: t = null; // should not happen
153: }
154: SHORT = t;
155: try {
156: t = new SimpleType(INTEGER_CLASSNAME);
157: } catch (OpenDataException e) {
158: t = null; // should not happen
159: }
160: INTEGER = t;
161: try {
162: t = new SimpleType(LONG_CLASSNAME);
163: } catch (OpenDataException e) {
164: t = null; // should not happen
165: }
166: LONG = t;
167: try {
168: t = new SimpleType(FLOAT_CLASSNAME);
169: } catch (OpenDataException e) {
170: t = null; // should not happen
171: }
172: FLOAT = t;
173: try {
174: t = new SimpleType(DOUBLE_CLASSNAME);
175: } catch (OpenDataException e) {
176: t = null; // should not happen
177: }
178: DOUBLE = t;
179: try {
180: t = new SimpleType(STRING_CLASSNAME);
181: } catch (OpenDataException e) {
182: t = null; // should not happen
183: }
184: STRING = t;
185: try {
186: t = new SimpleType(BIGDECIMAL_CLASSNAME);
187: } catch (OpenDataException e) {
188: t = null; // should not happen
189: }
190: BIGDECIMAL = t;
191: try {
192: t = new SimpleType(BIGINTEGER_CLASSNAME);
193: } catch (OpenDataException e) {
194: t = null; // should not happen
195: }
196: BIGINTEGER = t;
197: try {
198: t = new SimpleType(DATE_CLASSNAME);
199: } catch (OpenDataException e) {
200: t = null; // should not happen
201: }
202: DATE = t;
203: try {
204: t = new SimpleType("javax.management.ObjectName");
205: } catch (OpenDataException e) {
206: t = null; // should not happen
207: }
208: OBJECTNAME = t;
209: }
210:
211: private static final SimpleType[] typeArray = { VOID, BOOLEAN,
212: CHARACTER, BYTE, SHORT, INTEGER, LONG, FLOAT, DOUBLE,
213: STRING, BIGDECIMAL, BIGINTEGER, DATE, OBJECTNAME, DATE };
214:
215: private transient Integer myHashCode = null; // As this instance is immutable, these two values
216: private transient String myToString = null; // need only be calculated once.
217:
218: private static final Map canonicalTypes = new HashMap();
219: static {
220: for (int i = 0; i < typeArray.length; i++) {
221: final SimpleType type = typeArray[i];
222: canonicalTypes.put(type, type);
223: }
224: }
225:
226: /* *** Constructor *** */
227:
228: /**
229: * Constructs a SimpleType instance simply by calling <code>super(className, className, className)</code>.
230: *
231: * @throws OpenDataException if <var>className</var> is not one of the allowed Java class names for open data
232: */
233: private SimpleType(String className) throws OpenDataException {
234: // Check and construct state defined by parent.
235: //
236: super (className, className, className);
237: }
238:
239: /* *** SimpleType specific information methods *** */
240:
241: /**
242: * Tests whether <var>obj</var> is a value for this
243: * <code>SimpleType</code> instance. <p> This method returns
244: * <code>true</code> if and only if <var>obj</var> is not null and
245: * <var>obj</var>'s class name is the same as the className field
246: * defined for this <code>SimpleType</code> instance (ie the class
247: * name returned by the {@link OpenType#getClassName()
248: * getClassName} method).
249: *
250: * @param obj the object to be tested.
251: *
252: * @return <code>true</code> if <var>obj</var> is a value for this
253: * <code>SimpleType</code> instance.
254: */
255: public boolean isValue(Object obj) {
256:
257: // if obj is null, return false
258: //
259: if (obj == null) {
260: return false;
261: }
262:
263: // Test if obj's class name is the same as for this instance
264: //
265: return this .getClassName().equals(obj.getClass().getName());
266: }
267:
268: /* *** Methods overriden from class Object *** */
269:
270: /**
271: * Compares the specified <code>obj</code> parameter with this <code>SimpleType</code> instance for equality.
272: * <p>
273: * Two <code>SimpleType</code> instances are equal if and only if their
274: * {@link OpenType#getClassName() getClassName} methods return the same value.
275: *
276: * @param obj the object to be compared for equality with this <code>SimpleType</code> instance;
277: * if <var>obj</var> is <code>null</code> or is not an instance of the class <code>SimpleType</code>,
278: * <code>equals</code> returns <code>false</code>.
279: *
280: * @return <code>true</code> if the specified object is equal to this <code>SimpleType</code> instance.
281: */
282: public boolean equals(Object obj) {
283:
284: /* If it weren't for readReplace(), we could replace this method
285: with just:
286: return (this == obj);
287: */
288:
289: if (!(obj instanceof SimpleType))
290: return false;
291:
292: SimpleType other = (SimpleType) obj;
293:
294: // Test if other's className field is the same as for this instance
295: //
296: return this .getClassName().equals(other.getClassName());
297: }
298:
299: /**
300: * Returns the hash code value for this <code>SimpleType</code> instance.
301: * The hash code of a <code>SimpleType</code> instance is the the hash code of
302: * the string value returned by the {@link OpenType#getClassName() getClassName} method.
303: * <p>
304: * As <code>SimpleType</code> instances are immutable, the hash code for this instance is calculated once,
305: * on the first call to <code>hashCode</code>, and then the same value is returned for subsequent calls.
306: *
307: * @return the hash code value for this <code>SimpleType</code> instance
308: */
309: public int hashCode() {
310:
311: // Calculate the hash code value if it has not yet been done (ie 1st call to hashCode())
312: //
313: if (myHashCode == null) {
314: myHashCode = new Integer(this .getClassName().hashCode());
315: }
316:
317: // return always the same hash code for this instance (immutable)
318: //
319: return myHashCode.intValue();
320: }
321:
322: /**
323: * Returns a string representation of this <code>SimpleType</code> instance.
324: * <p>
325: * The string representation consists of
326: * the name of this class (ie <code>javax.management.openmbean.SimpleType</code>) and the type name
327: * for this instance (which is the java class name of the values this <code>SimpleType</code> instance represents).
328: * <p>
329: * As <code>SimpleType</code> instances are immutable, the string representation for this instance is calculated once,
330: * on the first call to <code>toString</code>, and then the same value is returned for subsequent calls.
331: *
332: * @return a string representation of this <code>SimpleType</code> instance
333: */
334: public String toString() {
335:
336: // Calculate the string representation if it has not yet been done (ie 1st call to toString())
337: //
338: if (myToString == null) {
339: myToString = this .getClass().getName() + "(name="
340: + getTypeName() + ")";
341: }
342:
343: // return always the same string representation for this instance (immutable)
344: //
345: return myToString;
346: }
347:
348: /**
349: * Replace an object read from an {@link
350: * java.io.ObjectInputStream} with the unique instance for that
351: * value.
352: *
353: * @return the replacement object.
354: *
355: * @exception ObjectStreamException if the read object cannot be
356: * resolved.
357: */
358: public Object readResolve() throws ObjectStreamException {
359: final SimpleType canonical = (SimpleType) canonicalTypes
360: .get(this );
361: if (canonical == null) {
362: // Should not happen
363: throw new InvalidObjectException("Invalid SimpleType: "
364: + this );
365: }
366: return canonical;
367: }
368:
369: public static void main(String[] args) {
370: System.out.println(SimpleType.VOID);
371: }
372: }
|