KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > eclipse > jdi > internal > ValueImpl


1 /*******************************************************************************
2  * Copyright (c) 2000, 2007 IBM Corporation and others.
3  * All rights reserved. This program and the accompanying materials
4  * are made available under the terms of the Eclipse Public License v1.0
5  * which accompanies this distribution, and is available at
6  * http://www.eclipse.org/legal/epl-v10.html
7  *
8  * Contributors:
9  * IBM Corporation - initial API and implementation
10  *******************************************************************************/

11 package org.eclipse.jdi.internal;
12
13
14 import java.io.DataInputStream JavaDoc;
15 import java.io.DataOutputStream JavaDoc;
16 import java.io.IOException JavaDoc;
17 import java.util.ArrayList JavaDoc;
18 import java.util.Iterator JavaDoc;
19 import java.util.List JavaDoc;
20
21 import org.eclipse.jdi.internal.jdwp.JdwpID;
22 import org.eclipse.jdi.internal.jdwp.JdwpObjectID;
23
24 import com.sun.jdi.ArrayType;
25 import com.sun.jdi.ClassNotLoadedException;
26 import com.sun.jdi.ClassType;
27 import com.sun.jdi.InterfaceType;
28 import com.sun.jdi.InternalException;
29 import com.sun.jdi.InvalidTypeException;
30 import com.sun.jdi.PrimitiveType;
31 import com.sun.jdi.ReferenceType;
32 import com.sun.jdi.Type;
33 import com.sun.jdi.Value;
34 import com.sun.jdi.VoidType;
35
36 /**
37  * this class implements the corresponding interfaces
38  * declared by the JDI specification. See the com.sun.jdi package
39  * for more information.
40  *
41  */

42 public abstract class ValueImpl extends MirrorImpl implements Value {
43     /**
44      * Creates new ValueImpl.
45      */

46     protected ValueImpl(String JavaDoc description, VirtualMachineImpl vmImpl) {
47         super(description, vmImpl);
48     }
49
50     /**
51      * @returns type of value.
52      */

53     public abstract Type type();
54
55     /**
56      * @returns type of value.
57      */

58     public abstract byte getTag();
59     
60     /**
61      * @return Reads JDWP representation and returns new instance.
62      */

63     public static ValueImpl readWithTag(MirrorImpl target, DataInputStream JavaDoc in) throws IOException JavaDoc {
64         byte tag = target.readByte("object tag", JdwpID.tagMap(), in); //$NON-NLS-1$
65
return readWithoutTag(target, tag, in);
66     }
67     
68     /**
69      * @return Reads JDWP representation and returns new instance.
70      */

71     public static ValueImpl readWithoutTag(MirrorImpl target, int type, DataInputStream JavaDoc in) throws IOException JavaDoc {
72         VirtualMachineImpl vmImpl = target.virtualMachineImpl();
73         // See also ArrayReference Impl.
74
switch(type) {
75             case ArrayReferenceImpl.tag:
76                 return ArrayReferenceImpl.read(target, in);
77             case ClassLoaderReferenceImpl.tag:
78                 return ClassLoaderReferenceImpl.read(target, in);
79             case ClassObjectReferenceImpl.tag:
80                 return ClassObjectReferenceImpl.read(target, in);
81             case StringReferenceImpl.tag:
82                 return StringReferenceImpl.read(target, in);
83             case ObjectReferenceImpl.tag:
84                 return ObjectReferenceImpl.readObjectRefWithoutTag(target, in);
85             case ThreadGroupReferenceImpl.tag:
86                 return ThreadGroupReferenceImpl.read(target, in);
87             case ThreadReferenceImpl.tag:
88                 return ThreadReferenceImpl.read(target, in);
89             case BooleanValueImpl.tag:
90                 return BooleanValueImpl.read(target, in);
91             case ByteValueImpl.tag:
92                 return ByteValueImpl.read(target, in);
93             case CharValueImpl.tag:
94                 return CharValueImpl.read(target, in);
95             case DoubleValueImpl.tag:
96                 return DoubleValueImpl.read(target, in);
97             case FloatValueImpl.tag:
98                 return FloatValueImpl.read(target, in);
99             case IntegerValueImpl.tag:
100                 return IntegerValueImpl.read(target, in);
101             case LongValueImpl.tag:
102                 return LongValueImpl.read(target, in);
103             case ShortValueImpl.tag:
104                 return ShortValueImpl.read(target, in);
105             case VoidValueImpl.tag:
106                 return new VoidValueImpl(vmImpl);
107             case 0:
108                 return null;
109             default:
110                 throw new InternalException(JDIMessages.ValueImpl_Invalid_Value_tag_encountered___1 + type);
111         }
112     }
113
114     /**
115      * Writes value with value tag.
116      */

117     public void writeWithTag(MirrorImpl target, DataOutputStream JavaDoc out) throws IOException JavaDoc {
118         target.writeByte(getTag(), "tag", JdwpID.tagMap(), out); //$NON-NLS-1$
119
write(target, out);
120     }
121
122     /**
123      * Writes value without value tag.
124      */

125     public abstract void write(MirrorImpl target, DataOutputStream JavaDoc out) throws IOException JavaDoc;
126     
127     /**
128      * Writes null value without value tag.
129      */

130     public static void writeNull(MirrorImpl target, DataOutputStream JavaDoc out) throws IOException JavaDoc {
131         JdwpObjectID nullID = new JdwpObjectID(target.virtualMachineImpl());
132         nullID.write(out);
133         if (target.fVerboseWriter != null)
134             target.fVerboseWriter.println("objectReference", nullID.value()); //$NON-NLS-1$
135
}
136     
137     /**
138      * Writes null value with value tag.
139      */

140     public static void writeNullWithTag(MirrorImpl target, DataOutputStream JavaDoc out) throws IOException JavaDoc {
141         target.writeByte(ObjectReferenceImpl.tag, "tag", JdwpID.tagMap(), out); //$NON-NLS-1$
142
writeNull(target, out);
143     }
144
145     /**
146      * Check the type and the vm of each values, according to the associated type.
147      * For primitive values, convert the value for match the given type if needed.
148      * The two list must have the same size.
149      * @return the (converted) values.
150      * @see checkValue(Value, Type, VirtualMachineImpl)
151      */

152     protected static List JavaDoc checkValues(List JavaDoc values, List JavaDoc types, VirtualMachineImpl vm) throws InvalidTypeException {
153         List JavaDoc result= new ArrayList JavaDoc(values.size());
154         Iterator JavaDoc iterValues= values.iterator();
155         Iterator JavaDoc iterTypes= types.iterator();
156         while (iterValues.hasNext()) {
157             Value value= (Value)iterValues.next();
158             Type type= (Type)iterTypes.next();
159             result.add(checkValue(value, type, vm));
160         }
161         return result;
162     }
163
164     /**
165      * Check the type and the vm of the given value.
166      * In case of primitive value, the value is converted if needed.
167      * @return the (converted) value.
168      * @throws InvalidTypeException if the given value is no assignment
169      * compatible with the given type.
170      * @see checkPrimitiveValue(PrimitiveValueImpl, PrimitiveTypeImpl, PrimitiveTypeImpl)
171      */

172     public static ValueImpl checkValue(Value value, Type type, VirtualMachineImpl vm) throws InvalidTypeException {
173         if (value == null) {
174             if (!(type instanceof PrimitiveType)) {
175                 return null;
176             }
177         } else {
178             vm.checkVM(value);
179             TypeImpl valueType= (TypeImpl)value.type();
180             if (valueType instanceof PrimitiveType && type instanceof PrimitiveType) {
181                 return checkPrimitiveValue((PrimitiveValueImpl) value, (PrimitiveTypeImpl) valueType, (PrimitiveTypeImpl) type);
182             }
183             if (valueType instanceof ReferenceType && type instanceof ReferenceType) {
184                 checkReferenceType((ReferenceType) valueType, (ReferenceType) type);
185                 return (ValueImpl)value;
186             }
187             if(valueType instanceof VoidType && type instanceof VoidType) {
188                 return (VoidValueImpl) value;
189             }
190         }
191         throw new InvalidTypeException(JDIMessages.ValueImpl_Type_of_the_value_not_compatible_with_the_expected_type__1);
192     }
193
194     /**
195      */

196     private static void checkReferenceType(ReferenceType valueType, ReferenceType type) throws InvalidTypeException {
197         if (valueType instanceof ArrayType) {
198             if (type instanceof ArrayType) {
199                 try {
200                     Type valueComponentType= ((ArrayType) valueType).componentType();
201                     Type componentType= ((ArrayType) type).componentType();
202                     if (valueComponentType instanceof PrimitiveType) {
203                         if (valueComponentType.equals(componentType)) {
204                             return;
205                         }
206                     } else if (valueComponentType instanceof ReferenceType && componentType instanceof ReferenceType) {
207                         checkReferenceType((ReferenceType) valueComponentType, (ReferenceType) componentType);
208                         return;
209                     }
210                 } catch (ClassNotLoadedException e) {
211                     // should not append
212
}
213             } else {
214                 // an array can be assigned to an object
215
if (type.signature().equals("Ljava/lang/Object;")) { //$NON-NLS-1$
216
return;
217                 }
218             }
219         } else {
220             if (type instanceof ClassType) {
221                 if (valueType instanceof ClassType) {
222                     ClassType superClass= (ClassType) valueType;
223                     while (superClass != null) {
224                         if (superClass.equals(type)) {
225                             return;
226                         }
227                         superClass= superClass.superclass();
228                     }
229                 } else if (valueType instanceof InterfaceType) {
230                     // an interface can be assigned to an object
231
if (type.signature().equals("Ljava/lang/Object;")) { //$NON-NLS-1$
232
return;
233                     }
234                 }
235             } else if (type instanceof InterfaceType) {
236                 if (valueType instanceof InterfaceType) {
237                     if (checkInterfaceType((InterfaceType) valueType, (InterfaceType) type)) {
238                         return;
239                     }
240                 } else {
241                     List JavaDoc interfaces= ((ClassType)valueType).allInterfaces();
242                     for (Iterator JavaDoc iter= interfaces.iterator(); iter.hasNext();) {
243                         if (checkInterfaceType((InterfaceType) iter.next(), (InterfaceType) type)) {
244                             return;
245                         }
246                     }
247                 }
248             }
249         }
250             
251         throw new InvalidTypeException(JDIMessages.ValueImpl_Type_of_the_value_not_compatible_with_the_expected_type__1);
252     }
253     
254     private static boolean checkInterfaceType(InterfaceType valueType, InterfaceType type) {
255         if (valueType.equals(type)) {
256             return true;
257         }
258         List JavaDoc superInterfaces= valueType.superinterfaces();
259         for (Iterator JavaDoc iter= superInterfaces.iterator(); iter.hasNext();) {
260             if (checkInterfaceType((InterfaceType) iter.next(), type)) {
261                 return true;
262             }
263         }
264         return false;
265     }
266
267     /**
268      * Check the type of the given value, and convert the value to the given
269      * type if needed (see Java Language Spec, section 5.2).
270      * @return the (converted) value.
271      * @throws InvalidTypeException if the given value is no assignment
272      * compatible with the given type.
273      */

274     protected static ValueImpl checkPrimitiveValue(PrimitiveValueImpl value, PrimitiveTypeImpl valueType, PrimitiveTypeImpl type) throws InvalidTypeException {
275         char valueTypeSignature= valueType.signature().charAt(0);
276         char typeSignature= type.signature().charAt(0);
277         if (valueTypeSignature == typeSignature) {
278             return value;
279         }
280         VirtualMachineImpl vm= value.virtualMachineImpl();
281         switch (typeSignature) {
282             case 'D':
283                 if (valueTypeSignature != 'Z') {
284                     return new DoubleValueImpl(vm, new Double JavaDoc(value.doubleValue()));
285                 }
286                 break;
287             case 'F':
288                 if (valueTypeSignature != 'Z' && valueTypeSignature != 'D') {
289                     return new FloatValueImpl(vm, new Float JavaDoc(value.floatValue()));
290                 }
291                 break;
292             case 'J':
293                 if (valueTypeSignature != 'Z' && valueTypeSignature != 'D' && valueTypeSignature != 'F') {
294                     return new LongValueImpl(vm, new Long JavaDoc(value.longValue()));
295                 }
296                 break;
297             case 'I':
298                 if (valueTypeSignature == 'B' || valueTypeSignature == 'C' || valueTypeSignature == 'S') {
299                     return new IntegerValueImpl(vm, new Integer JavaDoc(value.intValue()));
300                 }
301                 break;
302             case 'S':
303                 if (valueTypeSignature == 'B') {
304                     return new ShortValueImpl(vm, new Short JavaDoc(value.shortValue()));
305                 }
306                 break;
307         }
308         throw new InvalidTypeException(JDIMessages.ValueImpl_Type_of_the_value_not_compatible_with_the_expected_type__1);
309     }
310 }
311
Popular Tags