KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*******************************************************************************
2  * Copyright (c) 2000, 2005 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.ByteArrayOutputStream JavaDoc;
15 import java.io.DataInputStream JavaDoc;
16 import java.io.DataOutputStream JavaDoc;
17 import java.io.IOException JavaDoc;
18 import java.util.ArrayList JavaDoc;
19 import java.util.Iterator JavaDoc;
20 import java.util.List JavaDoc;
21
22 import org.eclipse.jdi.internal.jdwp.JdwpClassID;
23 import org.eclipse.jdi.internal.jdwp.JdwpClassObjectID;
24 import org.eclipse.jdi.internal.jdwp.JdwpCommandPacket;
25 import org.eclipse.jdi.internal.jdwp.JdwpID;
26 import org.eclipse.jdi.internal.jdwp.JdwpReplyPacket;
27
28 import com.sun.jdi.ClassNotLoadedException;
29 import com.sun.jdi.ClassNotPreparedException;
30 import com.sun.jdi.ClassType;
31 import com.sun.jdi.Field;
32 import com.sun.jdi.IncompatibleThreadStateException;
33 import com.sun.jdi.InvalidTypeException;
34 import com.sun.jdi.InvocationException;
35 import com.sun.jdi.Method;
36 import com.sun.jdi.ObjectReference;
37 import com.sun.jdi.ThreadReference;
38 import com.sun.jdi.Value;
39
40 /**
41  * this class implements the corresponding interfaces
42  * declared by the JDI specification. See the com.sun.jdi package
43  * for more information.
44  *
45  */

46 public class ClassTypeImpl extends ReferenceTypeImpl implements ClassType {
47     
48     /** JDWP Tag. */
49     public static final byte typeTag = JdwpID.TYPE_TAG_CLASS;
50
51     /** The following are the stored results of JDWP calls. */
52     private ClassTypeImpl fSuperclass = null;
53     
54     /**
55      * Creates new ClassTypeImpl.
56      */

57     public ClassTypeImpl(VirtualMachineImpl vmImpl, JdwpClassID classID) {
58         super("ClassType", vmImpl, classID); //$NON-NLS-1$
59
}
60     
61     /**
62      * Creates new ClassTypeImpl.
63      */

64     public ClassTypeImpl(VirtualMachineImpl vmImpl, JdwpClassID classID, String JavaDoc signature, String JavaDoc genericSignature) {
65         super("ClassType", vmImpl, classID, signature, genericSignature); //$NON-NLS-1$
66
}
67
68     /**
69      * @return Returns type tag.
70      */

71     public byte typeTag() {
72         return typeTag;
73     }
74     
75     /**
76      * @return Create a null value instance of the type.
77      */

78     public Value createNullValue() {
79         return new ClassObjectReferenceImpl(virtualMachineImpl(), new JdwpClassObjectID(virtualMachineImpl()));
80     }
81
82     /**
83      * Flushes all stored Jdwp results.
84      */

85     public void flushStoredJdwpResults() {
86         super.flushStoredJdwpResults();
87
88         // For all classes that have this class cached as superclass, this cache must be undone.
89
Iterator JavaDoc itr = virtualMachineImpl().allCachedRefTypes();
90         while (itr.hasNext()) {
91             ReferenceTypeImpl refType = (ReferenceTypeImpl)itr.next();
92             if (refType instanceof ClassTypeImpl) {
93                 ClassTypeImpl classType = (ClassTypeImpl)refType;
94                 if (classType.fSuperclass != null && classType.fSuperclass.equals(this)) {
95                     classType.flushStoredJdwpResults();
96                 }
97             }
98         }
99         
100         fSuperclass = null;
101     }
102     
103     /**
104      * @return Returns Jdwp version of given options.
105      */

106     private int optionsToJdwpOptions(int options) {
107         int jdwpOptions = 0;
108         if ((options & INVOKE_SINGLE_THREADED) != 0)
109             jdwpOptions |= MethodImpl.INVOKE_SINGLE_THREADED_JDWP;
110         return jdwpOptions;
111     }
112     
113     /**
114      * @return Returns a the single non-abstract Method visible from this class that has the given name and signature.
115      */

116     public Method concreteMethodByName(String JavaDoc name, String JavaDoc signature) {
117         /* Recursion is used to find the method:
118          * The methods of its own (own methods() command);
119          * The methods of it's superclass.
120          */

121          
122         Iterator JavaDoc methods = methods().iterator();
123         MethodImpl method;
124         while (methods.hasNext()) {
125             method = (MethodImpl)methods.next();
126             if (method.name().equals(name) && method.signature().equals(signature)) {
127                 if (method.isAbstract()) {
128                     return null;
129                 }
130                 return method;
131             }
132         }
133         
134         if (superclass() != null) {
135             return superclass().concreteMethodByName(name, signature);
136         }
137         
138         return null;
139     }
140
141     /**
142      * Invokes the specified static Method in the target VM.
143      * @return Returns a Value mirror of the invoked method's return value.
144      */

145     public Value invokeMethod(ThreadReference thread, Method method, List JavaDoc arguments, int options) throws InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException {
146         checkVM(thread);
147         checkVM(method);
148         ThreadReferenceImpl threadImpl = (ThreadReferenceImpl)thread;
149         MethodImpl methodImpl = (MethodImpl)method;
150
151         // Perform some checks for IllegalArgumentException.
152
if (!visibleMethods().contains(method))
153             throw new IllegalArgumentException JavaDoc(JDIMessages.ClassTypeImpl_Class_does_not_contain_given_method_1);
154         if (method.argumentTypeNames().size() != arguments.size())
155             throw new IllegalArgumentException JavaDoc(JDIMessages.ClassTypeImpl_Number_of_arguments_doesn__t_match_2);
156         if (method.isConstructor() || method.isStaticInitializer())
157             throw new IllegalArgumentException JavaDoc(JDIMessages.ClassTypeImpl_Method_is_constructor_or_intitializer_3);
158
159         // check the type and the vm of the arguments. Convert the values if needed
160
List JavaDoc checkedArguments= ValueImpl.checkValues(arguments, method.argumentTypes(), virtualMachineImpl());
161
162         initJdwpRequest();
163         try {
164             ByteArrayOutputStream JavaDoc outBytes = new ByteArrayOutputStream JavaDoc();
165             DataOutputStream JavaDoc outData = new DataOutputStream JavaDoc(outBytes);
166             write(this, outData);
167             threadImpl.write(this, outData);
168             methodImpl.write(this, outData);
169             
170             writeInt(checkedArguments.size(), "size", outData); //$NON-NLS-1$
171
Iterator JavaDoc iter = checkedArguments.iterator();
172             while(iter.hasNext()) {
173                 ValueImpl elt = (ValueImpl)iter.next();
174                 if (elt != null) {
175                     elt.writeWithTag(this, outData);
176                 } else {
177                     ValueImpl.writeNullWithTag(this, outData);
178                 }
179             }
180             
181             writeInt(optionsToJdwpOptions(options),"options", MethodImpl.getInvokeOptions(), outData); //$NON-NLS-1$
182

183             JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.CT_INVOKE_METHOD, outBytes);
184             switch (replyPacket.errorCode()) {
185                 case JdwpReplyPacket.INVALID_METHODID:
186                     throw new IllegalArgumentException JavaDoc();
187                 case JdwpReplyPacket.TYPE_MISMATCH:
188                     throw new InvalidTypeException();
189                 case JdwpReplyPacket.INVALID_CLASS:
190                     throw new ClassNotLoadedException(name());
191                 case JdwpReplyPacket.INVALID_THREAD:
192                     throw new IncompatibleThreadStateException();
193                 case JdwpReplyPacket.THREAD_NOT_SUSPENDED:
194                     throw new IncompatibleThreadStateException();
195             }
196             defaultReplyErrorHandler(replyPacket.errorCode());
197             DataInputStream JavaDoc replyData = replyPacket.dataInStream();
198             ValueImpl value = ValueImpl.readWithTag(this, replyData);
199             ObjectReferenceImpl exception = ObjectReferenceImpl.readObjectRefWithTag(this, replyData);
200             if (exception != null)
201                 throw new InvocationException(exception);
202             return value;
203         } catch (IOException JavaDoc e) {
204             defaultIOExceptionHandler(e);
205             return null;
206         } finally {
207             handledJdwpRequest();
208         }
209     }
210     
211     /**
212      * Constructs a new instance of this type, using the given constructor Method in the target VM.
213      * @return Returns Mirror of this type.
214      */

215     public ObjectReference newInstance(ThreadReference thread, Method method, List JavaDoc arguments, int options) throws InvalidTypeException, ClassNotLoadedException, IncompatibleThreadStateException, InvocationException {
216         checkVM(thread);
217         checkVM(method);
218         ThreadReferenceImpl threadImpl = (ThreadReferenceImpl)thread;
219         MethodImpl methodImpl = (MethodImpl)method;
220         
221         // Perform some checks for IllegalArgumentException.
222
if (!methods().contains(method))
223             throw new IllegalArgumentException JavaDoc(JDIMessages.ClassTypeImpl_Class_does_not_contain_given_method_4);
224         if (method.argumentTypeNames().size() != arguments.size())
225             throw new IllegalArgumentException JavaDoc(JDIMessages.ClassTypeImpl_Number_of_arguments_doesn__t_match_5);
226         if (!method.isConstructor())
227             throw new IllegalArgumentException JavaDoc(JDIMessages.ClassTypeImpl_Method_is_not_a_constructor_6);
228             
229         List JavaDoc checkedArguments= ValueImpl.checkValues(arguments, method.argumentTypes(), virtualMachineImpl());
230
231         initJdwpRequest();
232         try {
233             ByteArrayOutputStream JavaDoc outBytes = new ByteArrayOutputStream JavaDoc();
234             DataOutputStream JavaDoc outData = new DataOutputStream JavaDoc(outBytes);
235             write(this, outData);
236             threadImpl.write(this, outData);
237             methodImpl.write(this, outData);
238             
239             writeInt(checkedArguments.size(), "size", outData); //$NON-NLS-1$
240
Iterator JavaDoc iter = checkedArguments.iterator();
241             while(iter.hasNext()) {
242                 ValueImpl elt = (ValueImpl)iter.next();
243                 if (elt != null) {
244                     checkVM(elt);
245                     elt.writeWithTag(this, outData);
246                 } else {
247                     ValueImpl.writeNullWithTag(this, outData);
248                 }
249             }
250             
251             writeInt(optionsToJdwpOptions(options),"options", MethodImpl.getInvokeOptions(), outData); //$NON-NLS-1$
252

253             JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.CT_NEW_INSTANCE, outBytes);
254             switch (replyPacket.errorCode()) {
255                 case JdwpReplyPacket.INVALID_METHODID:
256                     throw new IllegalArgumentException JavaDoc();
257                 case JdwpReplyPacket.TYPE_MISMATCH:
258                     throw new InvalidTypeException();
259                 case JdwpReplyPacket.INVALID_CLASS:
260                     throw new ClassNotLoadedException(name());
261                 case JdwpReplyPacket.INVALID_THREAD:
262                     throw new IncompatibleThreadStateException();
263                 case JdwpReplyPacket.THREAD_NOT_SUSPENDED:
264                     throw new IncompatibleThreadStateException();
265             }
266             defaultReplyErrorHandler(replyPacket.errorCode());
267             DataInputStream JavaDoc replyData = replyPacket.dataInStream();
268             ObjectReferenceImpl object = ObjectReferenceImpl.readObjectRefWithTag(this, replyData);
269             ObjectReferenceImpl exception = ObjectReferenceImpl.readObjectRefWithTag(this, replyData);
270             if (exception != null)
271                 throw new InvocationException(exception);
272             return object;
273         } catch (IOException JavaDoc e) {
274             defaultIOExceptionHandler(e);
275             return null;
276         } finally {
277             handledJdwpRequest();
278         }
279     }
280     
281     /**
282      * Assigns a value to a static field. .
283      */

284     public void setValue(Field field, Value value) throws InvalidTypeException, ClassNotLoadedException {
285         // Note that this information should not be cached.
286
initJdwpRequest();
287         try {
288             ByteArrayOutputStream JavaDoc outBytes = new ByteArrayOutputStream JavaDoc();
289             DataOutputStream JavaDoc outData = new DataOutputStream JavaDoc(outBytes);
290             write(this, outData);
291             writeInt(1, "size", outData); // We only set one field //$NON-NLS-1$
292
checkVM(field);
293             ((FieldImpl)field).write(this, outData);
294             
295             // check the type and the vm of the value. Convert the value if needed
296
ValueImpl checkedValue= ValueImpl.checkValue(value, field.type(), virtualMachineImpl());
297             
298             if (checkedValue != null) {
299                 checkedValue.write(this, outData);
300             } else {
301                 ValueImpl.writeNull(this, outData);
302             }
303     
304             JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.CT_SET_VALUES, outBytes);
305             switch (replyPacket.errorCode()) {
306                 case JdwpReplyPacket.TYPE_MISMATCH:
307                     throw new InvalidTypeException();
308                 case JdwpReplyPacket.INVALID_CLASS:
309                     throw new ClassNotLoadedException(name());
310             }
311             defaultReplyErrorHandler(replyPacket.errorCode());
312         } catch (IOException JavaDoc e) {
313             defaultIOExceptionHandler(e);
314         } finally {
315             handledJdwpRequest();
316         }
317     }
318     
319     /**
320      * @return Returns the the currently loaded, direct subclasses of this class.
321      */

322     public List JavaDoc subclasses() {
323         // Note that this information should not be cached.
324
List JavaDoc subclasses = new ArrayList JavaDoc();
325         Iterator JavaDoc itr = virtualMachineImpl().allRefTypes();
326         while (itr.hasNext()) {
327             try {
328                 ReferenceTypeImpl refType = (ReferenceTypeImpl)itr.next();
329                 if (refType instanceof ClassTypeImpl) {
330                     ClassTypeImpl classType = (ClassTypeImpl)refType;
331                     if (classType.superclass() != null && classType.superclass().equals(this)) {
332                         subclasses.add(classType);
333                     }
334                 }
335             } catch (ClassNotPreparedException e) {
336                 continue;
337             }
338         }
339         return subclasses;
340     }
341     
342     /**
343      * @return Returns the superclass of this class.
344      */

345     public ClassType superclass() {
346         if (fSuperclass != null)
347             return fSuperclass;
348             
349         initJdwpRequest();
350         try {
351             JdwpReplyPacket replyPacket = requestVM(JdwpCommandPacket.CT_SUPERCLASS, this);
352             defaultReplyErrorHandler(replyPacket.errorCode());
353             DataInputStream JavaDoc replyData = replyPacket.dataInStream();
354             fSuperclass = ClassTypeImpl.read(this, replyData);
355             return fSuperclass;
356         } catch (IOException JavaDoc e) {
357             defaultIOExceptionHandler(e);
358             return null;
359         } finally {
360             handledJdwpRequest();
361         }
362     }
363     
364     /*
365      * @return Reads ID and returns known ReferenceTypeImpl with that ID, or if ID is unknown a newly created ReferenceTypeImpl.
366      */

367     public static ClassTypeImpl read(MirrorImpl target, DataInputStream JavaDoc in) throws IOException JavaDoc {
368         VirtualMachineImpl vmImpl = target.virtualMachineImpl();
369         JdwpClassID ID = new JdwpClassID(vmImpl);
370         ID.read(in);
371         if (target.fVerboseWriter != null)
372             target.fVerboseWriter.println("classType", ID.value()); //$NON-NLS-1$
373

374         if (ID.isNull())
375             return null;
376
377         ClassTypeImpl mirror = (ClassTypeImpl)vmImpl.getCachedMirror(ID);
378         if (mirror == null) {
379             mirror = new ClassTypeImpl(vmImpl, ID);
380             vmImpl.addCachedMirror(mirror);
381         }
382         return mirror;
383      }
384     
385     /*
386      * @return Reads ID and returns known ReferenceTypeImpl with that ID, or if ID is unknown a newly created ReferenceTypeImpl.
387      */

388     public static ClassTypeImpl readWithSignature(MirrorImpl target, boolean withGenericSignature, DataInputStream JavaDoc in) throws IOException JavaDoc {
389         VirtualMachineImpl vmImpl = target.virtualMachineImpl();
390         JdwpClassID ID = new JdwpClassID(vmImpl);
391         ID.read(in);
392         if (target.fVerboseWriter != null)
393             target.fVerboseWriter.println("classType", ID.value()); //$NON-NLS-1$
394

395         String JavaDoc signature = target.readString("signature", in); //$NON-NLS-1$
396
String JavaDoc genericSignature= null;
397         if (withGenericSignature) {
398             genericSignature= target.readString("generic signature", in); //$NON-NLS-1$
399
}
400         if (ID.isNull())
401             return null;
402             
403         ClassTypeImpl mirror = (ClassTypeImpl)vmImpl.getCachedMirror(ID);
404         if (mirror == null) {
405             mirror = new ClassTypeImpl(vmImpl, ID);
406             vmImpl.addCachedMirror(mirror);
407         }
408         mirror.setSignature(signature);
409         mirror.setGenericSignature(genericSignature);
410         return mirror;
411      }
412     
413     public boolean isEnum() {
414         if (virtualMachineImpl().isJdwpVersionGreaterOrEqual(1, 5)) {
415             // there is no modifier for this ... :(
416
ClassType superClass = superclass();
417             return superClass != null && "<E:Ljava/lang/Enum<TE;>;>Ljava/lang/Object;Ljava/lang/Comparable<TE;>;Ljava/io/Serializable;".equals(superClass.genericSignature()); //$NON-NLS-1$
418
}
419         // jdwp 1.5 only option
420
return false;
421     }
422     
423 }
424
Popular Tags