1 /*
2 * Copyright 1999-2006 Sun Microsystems, Inc. All Rights Reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Sun designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Sun in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
22 * CA 95054 USA or visit www.sun.com if you need additional information or
23 * have any questions.
24 */
25
26 package javax.management;
27
28
29 import com.sun.jmx.mbeanserver.GetPropertyAction;
30
31 import java.io.IOException;
32 import java.io.ObjectInputStream;
33 import java.io.ObjectOutputStream;
34 import java.io.ObjectStreamField;
35
36 import java.security.AccessController;
37
38 /**
39 * This class represents numbers that are arguments to relational constraints.
40 * A NumericValueExp may be used anywhere a ValueExp is required.
41 *
42 * <p>The <b>serialVersionUID</b> of this class is <code>-4679739485102359104L</code>.
43 *
44 * @serial include
45 *
46 * @since 1.5
47 */
48 @SuppressWarnings("serial") // serialVersionUID not constant
49 class NumericValueExp extends QueryEval implements ValueExp {
50
51 // Serialization compatibility stuff:
52 // Two serial forms are supported in this class. The selected form depends
53 // on system property "jmx.serial.form":
54 // - "1.0" for JMX 1.0
55 // - any other value for JMX 1.1 and higher
56 //
57 // Serial version for old serial form
58 private static final long oldSerialVersionUID = -6227876276058904000L;
59 //
60 // Serial version for new serial form
61 private static final long newSerialVersionUID = -4679739485102359104L;
62 //
63 // Serializable fields in old serial form
64 private static final ObjectStreamField[] oldSerialPersistentFields =
65 {
66 new ObjectStreamField("longVal", Long.TYPE),
67 new ObjectStreamField("doubleVal", Double.TYPE),
68 new ObjectStreamField("valIsLong", Boolean.TYPE)
69 };
70 //
71 // Serializable fields in new serial form
72 private static final ObjectStreamField[] newSerialPersistentFields =
73 {
74 new ObjectStreamField("val", Number.class)
75 };
76 //
77 // Actual serial version and serial form
78 private static final long serialVersionUID;
79
80 /**
81 * @serialField val Number The numeric value
82 *
83 * <p>The <b>serialVersionUID</b> of this class is <code>-4679739485102359104L</code>.
84 */
85 private static final ObjectStreamField[] serialPersistentFields;
86 private Number val = 0.0;
87
88 private static boolean compat = false;
89 static {
90 try {
91 GetPropertyAction act = new GetPropertyAction("jmx.serial.form");
92 String form = AccessController.doPrivileged(act);
93 compat = (form != null && form.equals("1.0"));
94 } catch (Exception e) {
95 // OK: exception means no compat with 1.0, too bad
96 }
97 if (compat) {
98 serialPersistentFields = oldSerialPersistentFields;
99 serialVersionUID = oldSerialVersionUID;
100 } else {
101 serialPersistentFields = newSerialPersistentFields;
102 serialVersionUID = newSerialVersionUID;
103 }
104 }
105 //
106 // END Serialization compatibility stuff
107
108
109 /**
110 * Basic constructor.
111 */
112 public NumericValueExp() {
113 }
114
115 /** Creates a new NumericValue representing the numeric literal <val>.*/
116 NumericValueExp(Number val)
117 {
118 this.val = val;
119 }
120
121 /**
122 * Returns a double numeric value
123 */
124 public double doubleValue() {
125 if (val instanceof Long || val instanceof Integer)
126 {
127 return (double)(val.longValue());
128 }
129 return val.doubleValue();
130 }
131
132 /**
133 * Returns a long numeric value
134 */
135 public long longValue() {
136 if (val instanceof Long || val instanceof Integer)
137 {
138 return val.longValue();
139 }
140 return (long)(val.doubleValue());
141 }
142
143 /**
144 * Returns true is if the numeric value is a long, false otherwise.
145 */
146 public boolean isLong() {
147 return (val instanceof Long || val instanceof Integer);
148 }
149
150 /**
151 * Returns the string representing the object
152 */
153 public String toString() {
154 if (val == null)
155 return "null";
156 if (val instanceof Long || val instanceof Integer)
157 {
158 return Long.toString(val.longValue());
159 }
160 double d = val.doubleValue();
161 if (Double.isInfinite(d))
162 return (d > 0) ? "(1.0 / 0.0)" : "(-1.0 / 0.0)";
163 if (Double.isNaN(d))
164 return "(0.0 / 0.0)";
165 return Double.toString(d);
166 }
167
168 /**
169 * Applies the ValueExp on a MBean.
170 *
171 * @param name The name of the MBean on which the ValueExp will be applied.
172 *
173 * @return The <CODE>ValueExp</CODE>.
174 *
175 * @exception BadStringOperationException
176 * @exception BadBinaryOpValueExpException
177 * @exception BadAttributeValueExpException
178 * @exception InvalidApplicationException
179 */
180 public ValueExp apply(ObjectName name)
181 throws BadStringOperationException, BadBinaryOpValueExpException,
182 BadAttributeValueExpException, InvalidApplicationException {
183 return this;
184 }
185
186 /**
187 * Deserializes a {@link NumericValueExp} from an {@link ObjectInputStream}.
188 */
189 private void readObject(ObjectInputStream in)
190 throws IOException, ClassNotFoundException {
191 if (compat)
192 {
193 // Read an object serialized in the old serial form
194 //
195 double doubleVal;
196 long longVal;
197 boolean isLong;
198 ObjectInputStream.GetField fields = in.readFields();
199 doubleVal = fields.get("doubleVal", (double)0);
200 if (fields.defaulted("doubleVal"))
201 {
202 throw new NullPointerException("doubleVal");
203 }
204 longVal = fields.get("longVal", (long)0);
205 if (fields.defaulted("longVal"))
206 {
207 throw new NullPointerException("longVal");
208 }
209 isLong = fields.get("valIsLong", false);
210 if (fields.defaulted("valIsLong"))
211 {
212 throw new NullPointerException("valIsLong");
213 }
214 if (isLong)
215 {
216 this.val = longVal;
217 }
218 else
219 {
220 this.val = doubleVal;
221 }
222 }
223 else
224 {
225 // Read an object serialized in the new serial form
226 //
227 in.defaultReadObject();
228 }
229 }
230
231
232 /**
233 * Serializes a {@link NumericValueExp} to an {@link ObjectOutputStream}.
234 */
235 private void writeObject(ObjectOutputStream out)
236 throws IOException {
237 if (compat)
238 {
239 // Serializes this instance in the old serial form
240 //
241 ObjectOutputStream.PutField fields = out.putFields();
242 fields.put("doubleVal", doubleValue());
243 fields.put("longVal", longValue());
244 fields.put("valIsLong", isLong());
245 out.writeFields();
246 }
247 else
248 {
249 // Serializes this instance in the new serial form
250 //
251 out.defaultWriteObject();
252 }
253 }
254
255 @Deprecated
256 public void setMBeanServer(MBeanServer s) {
257 super.setMBeanServer(s);
258 }
259
260 }