001    /* SimpleType.java -- Open type descriptor for the base types.
002       Copyright (C) 2006, 2007 Free Software Foundation, Inc.
003    
004    This file is part of GNU Classpath.
005    
006    GNU Classpath is free software; you can redistribute it and/or modify
007    it under the terms of the GNU General Public License as published by
008    the Free Software Foundation; either version 2, or (at your option)
009    any later version.
010    
011    GNU Classpath is distributed in the hope that it will be useful, but
012    WITHOUT ANY WARRANTY; without even the implied warranty of
013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
014    General Public License for more details.
015    
016    You should have received a copy of the GNU General Public License
017    along with GNU Classpath; see the file COPYING.  If not, write to the
018    Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
019    02110-1301 USA.
020    
021    Linking this library statically or dynamically with other modules is
022    making a combined work based on this library.  Thus, the terms and
023    conditions of the GNU General Public License cover the whole
024    combination.
025    
026    As a special exception, the copyright holders of this library give you
027    permission to link this library with independent modules to produce an
028    executable, regardless of the license terms of these independent
029    modules, and to copy and distribute the resulting executable under
030    terms of your choice, provided that you also meet, for each linked
031    independent module, the terms and conditions of the license of that
032    module.  An independent module is a module which is not derived from
033    or based on this library.  If you modify this library, you may extend
034    this exception to your version of the library, but you are not
035    obligated to do so.  If you do not wish to do so, delete this
036    exception statement from your version. */
037    
038    package javax.management.openmbean;
039    
040    import java.io.InvalidObjectException;
041    import java.io.ObjectStreamException;
042    
043    import java.math.BigDecimal;
044    import java.math.BigInteger;
045    
046    import java.util.Date;
047    
048    import 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     */
063    public 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    }