001/* SimpleType.java -- Open type descriptor for the base types.
002   Copyright (C) 2006, 2007 Free Software Foundation, Inc.
003
004This file is part of GNU Classpath.
005
006GNU Classpath is free software; you can redistribute it and/or modify
007it under the terms of the GNU General Public License as published by
008the Free Software Foundation; either version 2, or (at your option)
009any later version.
010
011GNU Classpath is distributed in the hope that it will be useful, but
012WITHOUT ANY WARRANTY; without even the implied warranty of
013MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014General Public License for more details.
015
016You should have received a copy of the GNU General Public License
017along with GNU Classpath; see the file COPYING.  If not, write to the
018Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
01902110-1301 USA.
020
021Linking this library statically or dynamically with other modules is
022making a combined work based on this library.  Thus, the terms and
023conditions of the GNU General Public License cover the whole
024combination.
025
026As a special exception, the copyright holders of this library give you
027permission to link this library with independent modules to produce an
028executable, regardless of the license terms of these independent
029modules, and to copy and distribute the resulting executable under
030terms of your choice, provided that you also meet, for each linked
031independent module, the terms and conditions of the license of that
032module.  An independent module is a module which is not derived from
033or based on this library.  If you modify this library, you may extend
034this exception to your version of the library, but you are not
035obligated to do so.  If you do not wish to do so, delete this
036exception statement from your version. */
037
038package javax.management.openmbean;
039
040import java.io.InvalidObjectException;
041import java.io.ObjectStreamException;
042
043import java.math.BigDecimal;
044import java.math.BigInteger;
045
046import java.util.Date;
047
048import javax.management.ObjectName;
049
050/**
051 * The open type descriptor for data values that are members
052 * of one of the simple types (such as an integer or a string).
053 * The other open types ({@link ArrayType}, {@link CompositeType},
054 * {@link TabularType}) are constructed from one or more of these
055 * types.  The simple types are formed from a small subset of
056 * basic Java types.  As a result, the valid instances of this
057 * class are predefined, and no constructor is given for creating
058 * new instances.
059 *
060 * @author Andrew John Hughes (gnu_andrew@member.fsf.org)
061 * @since 1.5
062 */
063public final class SimpleType<T>
064  extends OpenType<T>
065{
066
067  /**
068   * The {@link SimpleType} representation of
069   * <code>java.math.BigDecimal</code>.
070   */
071  public static final SimpleType<BigDecimal> BIGDECIMAL;
072
073  /**
074   * The {@link SimpleType} representation of
075   * <code>java.math.BigInteger</code>.
076   */
077  public static final SimpleType<BigInteger> BIGINTEGER;
078
079  /**
080   * The {@link SimpleType} representation of
081   * <code>java.lang.Boolean</code>.
082   */
083  public static final SimpleType<Boolean> BOOLEAN;
084
085  /**
086   * The {@link SimpleType} representation of
087   * <code>java.lang.Byte</code>.
088   */
089  public static final SimpleType<Byte> BYTE;
090
091  /**
092   * The {@link SimpleType} representation of
093   * <code>java.lang.Character</code>.
094   */
095  public static final SimpleType<Character> CHARACTER;
096
097  /**
098   * The {@link SimpleType} representation of
099   * <code>java.util.Date</code>.
100   */
101  public static final SimpleType<Date> DATE;
102
103  /**
104   * The {@link SimpleType} representation of
105   * <code>java.lang.Double</code>.
106   */
107  public static final SimpleType<Double> DOUBLE;
108
109  /**
110   * The {@link SimpleType} representation of
111   * <code>java.lang.Float</code>.
112   */
113  public static final SimpleType<Float> FLOAT;
114
115  /**
116   * The {@link SimpleType} representation of
117   * <code>java.lang.Integer</code>.
118   */
119  public static final SimpleType<Integer> INTEGER;
120
121  /**
122   * The {@link SimpleType} representation of
123   * <code>java.lang.Long</code>.
124   */
125  public static final SimpleType<Long> LONG;
126
127  /**
128   * The {@link SimpleType} representation of
129   * <code>javax.management.ObjectName</code>.
130   */
131  public static final SimpleType<ObjectName> OBJECTNAME;
132
133
134  /**
135   * The {@link SimpleType} representation of
136   * <code>java.lang.Short</code>.
137   */
138  public static final SimpleType<Short> SHORT;
139
140  /**
141   * The {@link SimpleType} representation of
142   * <code>java.lang.String</code>.
143   */
144  public static final SimpleType<String> STRING;
145
146  /**
147   * The {@link SimpleType} representation of
148   * <code>java.lang.Void</code>.
149   */
150  public static final SimpleType<Void> VOID;
151
152  /**
153   * Compatible with JDK 1.5
154   */
155  private static final long serialVersionUID = 2215577471957694503L;
156
157  /**
158   * The hash code of this instance.
159   */
160  private transient Integer hashCode;
161
162  /**
163   * The <code>toString()</code> result of this instance.
164   */
165  private transient String string;
166
167  /**
168   * Static construction of the {@link SimpleType} instances.
169   */
170  static
171  {
172    try
173      {
174        BIGDECIMAL = new SimpleType<BigDecimal>("java.math.BigDecimal");
175        BIGINTEGER = new SimpleType<BigInteger>("java.math.BigInteger");
176        BOOLEAN = new SimpleType<Boolean>("java.lang.Boolean");
177        BYTE = new SimpleType<Byte>("java.lang.Byte");
178        CHARACTER = new SimpleType<Character>("java.lang.Character");
179        DATE = new SimpleType<Date>("java.util.Date");
180        DOUBLE = new SimpleType<Double>("java.lang.Double");
181        FLOAT = new SimpleType<Float>("java.lang.Float");
182        INTEGER = new SimpleType<Integer>("java.lang.Integer");
183        LONG = new SimpleType<Long>("java.lang.Long");
184        OBJECTNAME =
185          new SimpleType<ObjectName>("javax.management.ObjectName");
186        SHORT = new SimpleType<Short>("java.lang.Short");
187        STRING = new SimpleType<String>("java.lang.String");
188        VOID = new SimpleType<Void>("java.lang.Void");
189      }
190    catch (OpenDataException e)
191      {
192        /* In normal circumstances, this shouldn't be possible. */
193        throw new IllegalStateException("A invalid class name " +
194                                        "was passed to the SimpleType " +
195                                        "constructor.", e);
196      }
197  }
198
199  /**
200   * Constructs a new {@link SimpleType} instance for the given
201   * class name.  The class name is also used as the type name
202   * and description of the {@link OpenType} instance.
203   *
204   * @param name the name of the class this instance should
205   *             represent.
206   * @throws OpenDataException if somehow the constructor of the
207   *                           superclass is passed an invalid
208   *                           class name.
209   */
210  private SimpleType(String name)
211    throws OpenDataException
212  {
213    super(name, name, name);
214  }
215
216  /**
217   * <p>
218   * Compares this simple data type with another object
219   * for equality.  The objects are judged to be equal if:
220   * </p>
221   * <ul>
222   * <li><code>obj</code> is not null.</li>
223   * <li><code>obj</code> is an instance of
224   * {@link SimpleType}.</li>
225   * <li>The class names are equal.</li>
226   * </ul>
227   *
228   * @param obj the object to compare with.
229   * @return true if the conditions above hold.
230   */
231  public boolean equals(Object obj)
232  {
233    if (!(obj instanceof SimpleType))
234      return false;
235    SimpleType<?> sType = (SimpleType<?>) obj;
236    return sType.getClassName().equals(getClassName());
237  }
238
239  /**
240   * <p>
241   * Returns the hash code of the simple data type.
242   * This is simply the hash code of the class name,
243   * which is the same element of the type compared
244   * as part of the
245   * {@link #equals(java.lang.Object)} method, thus ensuring
246   * that the hashcode is compatible with the equality
247   * test.
248   * </p>
249   * <p>
250   * As instances of this class are immutable, the hash code
251   * is computed just once for each instance and reused
252   * throughout its life.
253   * </p>
254   *
255   * @return the hash code of this instance.
256   */
257  public int hashCode()
258  {
259    if (hashCode == null)
260      hashCode = Integer.valueOf(getClassName().hashCode());
261    return hashCode.intValue();
262  }
263
264  /**
265   * Returns true if the specified object is a member of this
266   * simple type.  The object is judged to be so if it is
267   * non-null and its class name is the same as that returned
268   * by {@link SimpleType#getClassName()}.
269   *
270   * @param obj the object to test for membership.
271   * @return true if the object is a member of this type.
272   */
273  public boolean isValue(Object obj)
274  {
275    if (obj == null)
276      return false;
277    return obj.getClass().getName().equals(getClassName());
278  }
279
280  /**
281   * Replaces instances of this class read from an
282   * {@link java.io.ObjectInputStream} with one of the predefined
283   * values.  This ensures that each existing instance of
284   * this class is one of these unique instances.
285   *
286   * @return the replacement object.
287   * @throws ObjectStreamException if the object can not be
288   *                               resolved.
289   */
290  public Object readResolve()
291    throws ObjectStreamException
292  {
293    if (equals(BIGDECIMAL))
294      return BIGDECIMAL;
295    if (equals(BIGINTEGER))
296      return BIGINTEGER;
297    if (equals(BOOLEAN))
298      return BOOLEAN;
299    if (equals(BYTE))
300      return BYTE;
301    if (equals(CHARACTER))
302      return CHARACTER;
303    if (equals(DATE))
304      return DATE;
305    if (equals(DOUBLE))
306      return DOUBLE;
307    if (equals(FLOAT))
308      return FLOAT;
309    if (equals(INTEGER))
310      return INTEGER;
311    if (equals(LONG))
312      return LONG;
313    if (equals(OBJECTNAME))
314      return OBJECTNAME;
315    if (equals(SHORT))
316      return SHORT;
317    if (equals(STRING))
318      return STRING;
319    if (equals(VOID))
320      return VOID;
321    throw new InvalidObjectException("Invalid simple type instance " +
322                                     "deserialized.");
323  }
324
325  /**
326   * <p>
327   * Returns a textual representation of this instance.  This
328   * is constructed using the class name
329   * (<code>javax.management.openmbean.SimpleType</code>)
330   * and the name of the class the type represents.
331   * </p>
332   * <p>
333   * As instances of this class are immutable, the return value
334   * is computed just once for each instance and reused
335   * throughout its life.
336   * </p>
337   *
338   * @return a @link{java.lang.String} instance representing
339   *         the instance in textual form.
340   */
341  public String toString()
342  {
343    if (string == null)
344      string = getClass().getName()
345        + "[name=" + getClassName()
346        + "]";
347    return string;
348  }
349
350}