001 /*
002 * Copyright 2000-2007 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.management.openmbean;
027
028 // java import
029 //
030 import java.io.InvalidObjectException;
031 import java.io.ObjectStreamException;
032 import java.math.BigDecimal;
033 import java.math.BigInteger;
034 import java.util.Date;
035 import java.util.Map;
036 import java.util.HashMap;
037
038 // jmx import
039 //
040 import javax.management.ObjectName;
041
042 /**
043 * The <code>SimpleType</code> class is the <i>open type</i> class whose instances describe
044 * all <i>open data</i> values which are neither arrays,
045 * nor {@link CompositeData <code>CompositeData</code>} values,
046 * nor {@link TabularData <code>TabularData</code>} values.
047 * It predefines all its possible instances as static fields, and has no public constructor.
048 * <p>
049 * Given a <code>SimpleType</code> instance describing values whose Java class name is <i>className</i>,
050 * the internal fields corresponding to the name and description of this <code>SimpleType</code> instance
051 * are also set to <i>className</i>.
052 * In other words, its methods <code>getClassName</code>, <code>getTypeName</code> and <code>getDescription</code>
053 * all return the same string value <i>className</i>.
054 *
055 * @since 1.5
056 */
057 public final class SimpleType<T> extends OpenType<T> {
058
059 /* Serial version */
060 static final long serialVersionUID = 2215577471957694503L;
061
062 // SimpleType instances.
063 // IF YOU ADD A SimpleType, YOU MUST UPDATE OpenType and typeArray
064
065 /**
066 * The <code>SimpleType</code> instance describing values whose
067 * Java class name is <code>java.lang.Void</code>.
068 */
069 public static final SimpleType<Void> VOID = new SimpleType<Void>(
070 Void.class);
071
072 /**
073 * The <code>SimpleType</code> instance describing values whose
074 * Java class name is <code>java.lang.Boolean</code>.
075 */
076 public static final SimpleType<Boolean> BOOLEAN = new SimpleType<Boolean>(
077 Boolean.class);
078
079 /**
080 * The <code>SimpleType</code> instance describing values whose
081 * Java class name is <code>java.lang.Character</code>.
082 */
083 public static final SimpleType<Character> CHARACTER = new SimpleType<Character>(
084 Character.class);
085
086 /**
087 * The <code>SimpleType</code> instance describing values whose
088 * Java class name is <code>java.lang.Byte</code>.
089 */
090 public static final SimpleType<Byte> BYTE = new SimpleType<Byte>(
091 Byte.class);
092
093 /**
094 * The <code>SimpleType</code> instance describing values whose
095 * Java class name is <code>java.lang.Short</code>.
096 */
097 public static final SimpleType<Short> SHORT = new SimpleType<Short>(
098 Short.class);
099
100 /**
101 * The <code>SimpleType</code> instance describing values whose
102 * Java class name is <code>java.lang.Integer</code>.
103 */
104 public static final SimpleType<Integer> INTEGER = new SimpleType<Integer>(
105 Integer.class);
106
107 /**
108 * The <code>SimpleType</code> instance describing values whose
109 * Java class name is <code>java.lang.Long</code>.
110 */
111 public static final SimpleType<Long> LONG = new SimpleType<Long>(
112 Long.class);
113
114 /**
115 * The <code>SimpleType</code> instance describing values whose
116 * Java class name is <code>java.lang.Float</code>.
117 */
118 public static final SimpleType<Float> FLOAT = new SimpleType<Float>(
119 Float.class);
120
121 /**
122 * The <code>SimpleType</code> instance describing values whose
123 * Java class name is <code>java.lang.Double</code>.
124 */
125 public static final SimpleType<Double> DOUBLE = new SimpleType<Double>(
126 Double.class);
127
128 /**
129 * The <code>SimpleType</code> instance describing values whose
130 * Java class name is <code>java.lang.String</code>.
131 */
132 public static final SimpleType<String> STRING = new SimpleType<String>(
133 String.class);
134
135 /**
136 * The <code>SimpleType</code> instance describing values whose
137 * Java class name is <code>java.math.BigDecimal</code>.
138 */
139 public static final SimpleType<BigDecimal> BIGDECIMAL = new SimpleType<BigDecimal>(
140 BigDecimal.class);
141
142 /**
143 * The <code>SimpleType</code> instance describing values whose
144 * Java class name is <code>java.math.BigInteger</code>.
145 */
146 public static final SimpleType<BigInteger> BIGINTEGER = new SimpleType<BigInteger>(
147 BigInteger.class);
148
149 /**
150 * The <code>SimpleType</code> instance describing values whose
151 * Java class name is <code>java.util.Date</code>.
152 */
153 public static final SimpleType<Date> DATE = new SimpleType<Date>(
154 Date.class);
155
156 /**
157 * The <code>SimpleType</code> instance describing values whose
158 * Java class name is <code>javax.management.ObjectName</code>.
159 */
160 public static final SimpleType<ObjectName> OBJECTNAME = new SimpleType<ObjectName>(
161 ObjectName.class);
162
163 private static final SimpleType[] typeArray = { VOID, BOOLEAN,
164 CHARACTER, BYTE, SHORT, INTEGER, LONG, FLOAT, DOUBLE,
165 STRING, BIGDECIMAL, BIGINTEGER, DATE, OBJECTNAME, };
166
167 private transient Integer myHashCode = null; // As this instance is immutable, these two values
168 private transient String myToString = null; // need only be calculated once.
169
170 /* *** Constructor *** */
171
172 private SimpleType(Class<T> valueClass) {
173 super (valueClass.getName(), valueClass.getName(), valueClass
174 .getName(), false);
175 }
176
177 /* *** SimpleType specific information methods *** */
178
179 /**
180 * Tests whether <var>obj</var> is a value for this
181 * <code>SimpleType</code> instance. <p> This method returns
182 * <code>true</code> if and only if <var>obj</var> is not null and
183 * <var>obj</var>'s class name is the same as the className field
184 * defined for this <code>SimpleType</code> instance (ie the class
185 * name returned by the {@link OpenType#getClassName()
186 * getClassName} method).
187 *
188 * @param obj the object to be tested.
189 *
190 * @return <code>true</code> if <var>obj</var> is a value for this
191 * <code>SimpleType</code> instance.
192 */
193 public boolean isValue(Object obj) {
194
195 // if obj is null, return false
196 //
197 if (obj == null) {
198 return false;
199 }
200
201 // Test if obj's class name is the same as for this instance
202 //
203 return this .getClassName().equals(obj.getClass().getName());
204 }
205
206 /* *** Methods overriden from class Object *** */
207
208 /**
209 * Compares the specified <code>obj</code> parameter with this <code>SimpleType</code> instance for equality.
210 * <p>
211 * Two <code>SimpleType</code> instances are equal if and only if their
212 * {@link OpenType#getClassName() getClassName} methods return the same value.
213 *
214 * @param obj the object to be compared for equality with this <code>SimpleType</code> instance;
215 * if <var>obj</var> is <code>null</code> or is not an instance of the class <code>SimpleType</code>,
216 * <code>equals</code> returns <code>false</code>.
217 *
218 * @return <code>true</code> if the specified object is equal to this <code>SimpleType</code> instance.
219 */
220 public boolean equals(Object obj) {
221
222 /* If it weren't for readReplace(), we could replace this method
223 with just:
224 return (this == obj);
225 */
226
227 if (!(obj instanceof SimpleType))
228 return false;
229
230 SimpleType other = (SimpleType) obj;
231
232 // Test if other's className field is the same as for this instance
233 //
234 return this .getClassName().equals(other.getClassName());
235 }
236
237 /**
238 * Returns the hash code value for this <code>SimpleType</code> instance.
239 * The hash code of a <code>SimpleType</code> instance is the the hash code of
240 * the string value returned by the {@link OpenType#getClassName() getClassName} method.
241 * <p>
242 * As <code>SimpleType</code> instances are immutable, the hash code for this instance is calculated once,
243 * on the first call to <code>hashCode</code>, and then the same value is returned for subsequent calls.
244 *
245 * @return the hash code value for this <code>SimpleType</code> instance
246 */
247 public int hashCode() {
248
249 // Calculate the hash code value if it has not yet been done (ie 1st call to hashCode())
250 //
251 if (myHashCode == null) {
252 myHashCode = new Integer(this .getClassName().hashCode());
253 }
254
255 // return always the same hash code for this instance (immutable)
256 //
257 return myHashCode.intValue();
258 }
259
260 /**
261 * Returns a string representation of this <code>SimpleType</code> instance.
262 * <p>
263 * The string representation consists of
264 * the name of this class (ie <code>javax.management.openmbean.SimpleType</code>) and the type name
265 * for this instance (which is the java class name of the values this <code>SimpleType</code> instance represents).
266 * <p>
267 * As <code>SimpleType</code> instances are immutable, the string representation for this instance is calculated once,
268 * on the first call to <code>toString</code>, and then the same value is returned for subsequent calls.
269 *
270 * @return a string representation of this <code>SimpleType</code> instance
271 */
272 public String toString() {
273
274 // Calculate the string representation if it has not yet been done (ie 1st call to toString())
275 //
276 if (myToString == null) {
277 myToString = this .getClass().getName() + "(name="
278 + getTypeName() + ")";
279 }
280
281 // return always the same string representation for this instance (immutable)
282 //
283 return myToString;
284 }
285
286 private static final Map<SimpleType, SimpleType> canonicalTypes = new HashMap<SimpleType, SimpleType>();
287 static {
288 for (int i = 0; i < typeArray.length; i++) {
289 final SimpleType type = typeArray[i];
290 canonicalTypes.put(type, type);
291 }
292 }
293
294 /**
295 * Replace an object read from an {@link
296 * java.io.ObjectInputStream} with the unique instance for that
297 * value.
298 *
299 * @return the replacement object.
300 *
301 * @exception ObjectStreamException if the read object cannot be
302 * resolved.
303 */
304 public Object readResolve() throws ObjectStreamException {
305 final SimpleType canonical = canonicalTypes.get(this );
306 if (canonical == null) {
307 // Should not happen
308 throw new InvalidObjectException("Invalid SimpleType: "
309 + this);
310 }
311 return canonical;
312 }
313 }
|